//-----------------------------------------------------------------------------
// 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:
//      Resource Management Service (Server)
//
// Author:  Jie Chen
//
// Revision History:
//   rsvcServer.cc,v
// Revision 1.2  1998/02/11  18:46:45  akers
// Ongoing development
//
// Revision 1.1  1998/01/22  17:08:19  akers
// Addition of new NameServer
//
//
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifndef _WIN32
#include <sys/resource.h>
#endif

#include <rsvcConfig.h>
#include <rsvcServerConfig.h>
#include <rsvcDataStore.h>
#include <rsvcDataStoreTable.h>
#include <rsvcAcceptor.h>
#include <rsvcUdpHandler.h>
#include <rsvcSignal.h>
#include <cdevReactor.h>

int          rsvc_finished = 0;
cdevReactor* rsvc_reactor = 0;

extern void rsvcLocalConfig (rsvcDataStoreTable& table);

int main (int argc, char** argv)
{
  // first parse server configuraton file
  if (argc > 1) 
    rsvcServerConfig::configure (argv[1]);
  else
    rsvcServerConfig::configure ();

#ifndef _WIN32
  // change limit on how many files can be open at a time
  struct rlimit limit, nlimit;  
  if (getrlimit (RLIMIT_NOFILE, &limit) != 0) 
    printf ("Cannot get resouce limit\n");
  else {
    printf ("RSVC Info: Current limit on number of opened files is %d\n", 
	    limit.rlim_cur);

    nlimit.rlim_cur = rsvcServerConfig::maxNoFiles ();
    nlimit.rlim_max = limit.rlim_max;
    if (setrlimit (RLIMIT_NOFILE, &nlimit) != 0) 
      printf ("RSVC Info: Cannot change the limit on number of opened files\n");
    else {
      if (getrlimit (RLIMIT_NOFILE, &limit) == 0) 
	printf ("RSVC Info: Limit on number of opened files has been changed to %d\n", 
		limit.rlim_cur);
      else
	printf ("RSVC Info: Cannot change the limit on number of opened files\n");
    }
  }
#endif
  
  // create data store table
  rsvcDataStoreTable   table;

  // create reactor
  cdevReactor     reactor;
  rsvc_reactor  = &reactor;

#ifdef _CDEV_MANAGE_SERVERS
  // create udp handler
  rsvcUdpHandler       udphandler (_RSVC_CDEV_SERVERS,
				   reactor, table);
  if (udphandler.open (rsvcServerConfig::serverPort ()) == -1) {
    fprintf (stderr, "Cannot open udp handler at port %d\n",
	     rsvcServerConfig::serverPort ());
    exit (1);
  }
  printf ("RSVC Info: rsvc server opens a udp port at %d\n",
	  udphandler.port_number ());

  if (reactor.registerHandler (&udphandler,
				cdevEventHandler::READ_MASK) == -1) {
    fprintf (stderr, "Cannot register udp handler\n");
    exit (1);
  }
#endif
  
  // create TCP handler
  rsvcAcceptor         acceptor   (reactor, table);
  if (acceptor.open   (rsvcServerConfig::port ()) == -1) {
    fprintf (stderr, "Cannot open TCP handler at port %d\n",
	     rsvcServerConfig::port ());
    exit (1);
  }

  printf ("RSVC Info: rsvc server opens a tcp port at %d\n",
	  acceptor.port_number ());

  if (reactor.registerHandler (&acceptor,
				cdevEventHandler::READ_MASK) == -1) {
    fprintf (stderr, "Cannot register tcp handler\n");
    exit (1);
  }

  if (rsvcSignal::registerSignalHandlers () != 0) {
    fprintf (stderr, "RSVC Error: Cannot register signal handler\n");
    exit (1);
  }

  // open a set of databases that are listed in the config file
  char** names = rsvcServerConfig::defaultDbases ();
  int    i = 0;
  if (names) {
    while (names[i] != 0) {
      if (table.openDatabase (names[i]) == RSVC_SUCCESS) 
	printf ("Database <%s> is open and registerd\n", names[i]);
      i++;
    }
  }

  // start up local configuration
  rsvcLocalConfig (table);

  printf ("Starting up rsvc server .....................\n");

  while (!rsvc_finished) reactor.handleEvents ();
  printf ("Shutting down rsvc server\n");

  return 0;
}

  
