# include "opihi.h"

static int server = 0;
static int bufferPending = FALSE;

// XXX this is rather pantasks-specific...
void multicommand_InitServer () {

  char hostname[256], PASSWORD[256];

  if (server != 0) {
    /* check if down? */
    fprintf (stderr, "error: server fd already defined\n");
    exit (1);
  }

  /* find the defined server hostname */
  if (VarConfig ("PANTASKS_SERVER", "%s", hostname) == NULL) {
    gprint (GP_ERR, "pantasks server host undefined\n");
    exit (2);
  }

  /* attempt to connect to the server */
  server = GetClientSocket (hostname);

  /* here we can perform the security handshaking */
  VarConfig ("PASSWORD", "%s", PASSWORD);
  SendCommand (server, strlen(PASSWORD), PASSWORD);
  
  return;
}

/* take input line and split into multiple lines
   at the semi-colons.  send these to 'command' */

int multicommand (char *line) {
 
  int done, status, verbose;
  char *p, *q, *tmpline, *outline;
  IOBuffer message;

  /* if no server is defined, use 'verbose' mode for 'command' */ 
  verbose = (server == 0);

  p = line; 
  done = FALSE;
  status = TRUE;
  while (!done) {
    q = strchr (p, ';');
    if (q == NULL) {
      q = p + strlen(p);
      done = TRUE;
    }
    tmpline = strncreate (p, q - p);
    stripwhite (tmpline);
    if (*tmpline) {

      if (bufferPending) {
	// flush old messages
	while (ExpectMessage (server, 0.2, &message));
	bufferPending = FALSE;
      }

      status = command (tmpline, &outline, verbose);

      if (status == -1) {
	if (server) {
	  // send the command to the server instead
	  if (!SendMessage (server, outline)) {
	    switch (errno) {
	      case EPIPE:
		gprint (GP_ERR, "server connection has died\n");
		exit (1);
	      default:
		gprint (GP_ERR, "server is busy...\n");
		bufferPending = TRUE;
		goto escape;
	    }
	  }

	  // receive the command exit status
	  if (ExpectMessage (server, 2.0, &message)) {
	    switch (errno) {
	      case EPIPE:
		gprint (GP_ERR, "server connection has died\n");
		exit (1);
	      default:
		gprint (GP_ERR, "server is busy...\n");
		bufferPending = TRUE;
		goto escape;
	    }
	  } else {
	    sscanf (message.buffer, "STATUS %d", &status);
	  }

	  // receive the resulting stderr
	  if (ExpectMessage (server, 2.0, &message)) {
	    switch (errno) {
	      case EPIPE:
		gprint (GP_ERR, "server connection has died\n");
		exit (1);
	      default:
		gprint (GP_ERR, "server is busy...\n");
		bufferPending = TRUE;
		goto escape;
	    }
	  } else {
	    gwrite (message.buffer, 1, message.Nbuffer, GP_ERR);
	  }

	  // receive the resulting stdout
	  if (ExpectMessage (server, 2.0, &message)) {
	    switch (errno) {
	      case EPIPE:
		gprint (GP_ERR, "server connection has died\n");
		exit (1);
	      default:
		gprint (GP_ERR, "server is busy...\n");
		bufferPending = TRUE;
		goto escape;
	    }
	  } else {
	    gwrite (message.buffer, 1, message.Nbuffer, GP_LOG);
	  }
	} else {
	  // if no server is defined, we treat an unknown command as an error
	  status = FALSE;
	}	
      }
    escape:
      if (outline != NULL) free (outline);
      if (!status && auto_break) done = TRUE;
    }
    p = q + 1;
  }
  return (status);
}

/* should skip ; surrounded by "" */

/* commands which are not found are sent to the server socket if 
   defined. commands executed by the server return their stderr
   and stdout streams.  server commands should probably not block
   the server for very long or multiple clients will interfere
   with each other.  
*/
