# include "pantasks.h"

/* pantasks-server is not a readline program.
   it runs three (or four) threads:
   - one thread listens on the socket for incomming connections 
     and performs client validation
   - one thread parses commands from the connected clients
   - one thread runs the scheduler loop
   - one thread may run the controller loop independently
   
   * note: the client shell traps certain commands and performs them
   locally. at a minimum: help.  perhaps: input, other I/O commands?
*/

/* program-dependent initialization */
int main (int argc, char **argv) {
  
  char log_stdout[128], log_stderr[128];
  pthread_t jobsThread;
  pthread_t tasksThread;
  pthread_t inputsThread;
  pthread_t clientsThread;
  pthread_t controllerThread;
  int InitSocket, BindSocket;
  SockAddress Address;

  general_init (&argc, argv);

  // define server output log files
  if (VarConfig ("PANTASKS_SERVER_STDOUT", "%s", log_stdout) != NULL) {
      gprintSetFile (GP_LOG, log_stdout);
  }
  if (VarConfig ("PANTASKS_SERVER_STDERR", "%s", log_stderr) != NULL) {
      gprintSetFile (GP_ERR, log_stderr);
  }

  DefineValidIP ();

  /* XXX not sure what is a good setting for this in the server */
  auto_break = TRUE;

  /* load the commands used by this implementation */
  InitBasic ();
  InitData ();
  InitPantasksServer ();
  
  InitInputs ();

  { 
    char *modules;
    static char *datadir = "@DATADIR@";
    ALLOCATE (modules, char, strlen(datadir) + strlen("/modules") + 2);
    sprintf (modules, "%s/modules", datadir);
    set_str_variable ("MODULES:0", modules);
    set_int_variable ("MODULES:n", 1);
    free (modules);
  }

  signal (SIGPIPE, gotsignal);
  // signal (SIGTSTP, gotsignal);
  // signal (SIGTTIN, gotsignal);
  signal (SIGINT, SIG_DFL);

  startup (&argc, argv);

  /* start up the background threads here */
  pthread_create (&clientsThread,    NULL, &ListenClients,    	   NULL);
  pthread_create (&tasksThread,      NULL, &CheckTasksThread, 	   NULL);
  pthread_create (&jobsThread,       NULL, &CheckJobsThread,  	   NULL);
  pthread_create (&controllerThread, NULL, &CheckControllerThread, NULL);
  pthread_create (&inputsThread,     NULL, &CheckInputsThread,     NULL);

  /* in this loop, we listen for incoming connections, validate, and
     pass them to the ListenClient thread */

  /* create the listening socket */
  InitSocket = InitServerSocket (&Address);
  
  InitPassword ();

  while (1) {

    /* wait for clients to make connection */
    BindSocket = WaitServerSocket (InitSocket, &Address);
    if (BindSocket == -1) continue;

    /* validate : wait for password */
    if (!CheckPassword (BindSocket)) continue;
    
    AddNewClient (BindSocket);
  }
}

/* add program-dependent exit functions here */
void cleanup () {
  QuitKapa ();
  QuitController ();
  return;
}

void gotsignal (int signum) {
  gprint (GP_ERR, "got signal : %d\n", signum);
  return;
}

/* these are needed to resolve symbols expected by libshell.so */
void welcome () { }
void program_init (int *argc, char **argv) {}
