//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
//
// Description:
//      Implementation of cdev interface to resouce service client
//
//      This is only a subset of whole APIs of rsvc client
//
// Author:  Jie Chen
//
//
//
#ifndef _NS_SERVICE_H
#define _NS_SERVICE_H

#ifndef _CDEV_MANAGE_SERVERS
#define _CDEV_MANAGE_SERVERS
#endif

#include <stdio.h>
#include <string.h>
#include <cdevService.h>
#include <cdevRequestObject.h>
#include <cdevSlist.h>
#include <rsvcClient.h>
#include <rsvcSpec.h>

extern "C" RSVCAPI cdevService * newRnsService (char* name, cdevSystem* system);

class rnsMonitorObj;
class rnsRequestObject;

class rnsService: public cdevService
{
public:
  // cornstructor
  rnsService (char* name, cdevSystem& system = cdevSystem::defaultSystem ());
  
  int getFd (int * &fd, int &numFd);
  // PURPOSE: return channel access network file descriptors
  // REQUIRE: callers provide pointer only and don't free memory
  // PROMISE: numFd will be real number of file descriptors of the 
  //          channel access client. return 0: always

  int flush (void);
  // PURPOSE: flush network requests
  // REQUIRE: nothing
  // PROMISE: return CDEV_SUCCESS: success

  int poll (void);
  // PURPOSE: polling method
  // REQUIRE: nothing
  // PROMISE: return CDEV_SUCCESS: success. Else error

  int pend (int fd = -1);
  // PURPOSE: handle network pending 
  // REQUIRE: nothing
  // PROMISE: return CDEV_SUCCESS: success, else error

  int pend (double seconds, int fd = -1);
  // PURPOSE: handle network pending for 'seconds'
  // REQUIRE: nothing
  // PROMISE: return 0: success. return CDEV_TIMEOUT for timeout

  int getRequestObject (char *deviceName, char *msg,
			cdevRequestObject * &req);
  // PURPOSE: return a rnsRequestObject (called from attachPtr function
  //          of cdevRequestObject class)
  // REQUIRE: right pair of deviceName and msg. 
  // PROMISE: a rnsRequestObject

  int getNameServer (cdevDevice* &rns);
  // PURPOSE: retrieve ca name server in case of missing DDL
  // REQUIRE: nothing
  // PROMISE: 

  int monitorsRestarted       (void);
  // PURPOSE: check whether all monitors have been restarted or not
  // REQUIRE: nothing
  // PROMISE: 1: yes, 0: no

  int reconnect               (void);
  // PURPOSE: reconnect to name server
  // REQUIRE: nothing
  // PROMISE: CDEV_SUCCESS on sucessful connection

  const char* className (void) const {return "rnsService";}

protected:

  // deny direct access to destructor
  ~rnsService (void);

  // add a monitor object
  int addMonitorObject        (rnsMonitorObj* obj);
  // remove a monitor object
  int removeMonitorObject     (rnsMonitorObj* obj);
  // check whether this callback is in the list
  rnsMonitorObj* hasCallback  (cdevCallback& cbk);

  // server disconnection callback
  static void discCallback   (int status, void* arg, rsvcData* data);

private:
  rsvcClient client_;
  int        *fds_;
  int        numFds_;

  // list of monitor object
  cdevSlist  monobjs_;

  // all tags needed for this service
  static char* tags_[];

  // number of tags needed for this service
  static int   numtags_;

  // friend class 
  friend class rnsRequestObject;
};
#endif

