#include "config.h"
#include "acap_options.h"
#include "acap_parse.h"
#include "util.h"
#include "log.h"

#include <stdio.h>
#include <errno.h>
#include <setjmp.h>
#include <unistd.h>
#include <signal.h>

/* globals */
jmp_buf env;

static void catchSIGALARM()
{
  longjmp(env, 1);
}

int
main(int argc, char **argv)
{
  FILE *input = NULL, *output = NULL;
  char buf[MAX_LINE_LEN+1];
  ParseReturn pr;

  FILE *session_dump;

  if (LOG_SESSION) {
    session_dump = fopen(SESSION_FILE, "w");
  }

  (void) signal(SIGALRM, catchSIGALARM);
  alarm(0);

  openlog("sievead", LOG_PID, LOG_MAIL);

  lprintf(LOG_INFO, "Program starting");

  if ((input=fdopen(INPUT_FD, "r"))==NULL||
      (output=fdopen(OUTPUT_FD, "w"))==NULL) {
    lprintf(LOG_ERR, "Failed to open input/output streams");
    perror(argv[0]);
    exit(1);
  }

  acapParseInit();
  fprintf(output, "* ACAP (SASL \"PLAIN\")\r\n");
  if (LOG_SESSION) {
    fprintf(session_dump, "s: * ACAP (SASL \"PLAIN\")\r\n");
  }

  while (1) {

    alarm(TIMEOUT);
    if (setjmp(env)) {
      fprintf(output, "* BYE ");
      fprintf(output, "\"Auto-logout; idle for too long (%d seconds)\"\r\n",
	      TIMEOUT);
      if (LOG_SESSION) {
	fprintf(session_dump,
		"s: * BYE \"Auto-logout; idle for too long (%d seconds)\"\r\n",
		TIMEOUT);
      }
      lprintf(LOG_INFO, "Auto-logout; client idle too long");
      break;
    }
    fflush(output);
    if (LOG_SESSION) {
      fflush(session_dump);
    }
    fgets(buf, sizeof(buf), input);
    alarm(0);

    if (feof(input))
      break;
    if (containsCRLF(buf)) {

      if (LOG_SESSION) {
	fprintf(session_dump, "c: %s", buf);
      }

      pr=acapParse(buf);
      if (pr.result==MoreToCome) {
	do {
	  if (pr.outstr) {
	    fprintf(output, pr.outstr);

	    if (LOG_SESSION) {
	      fprintf(session_dump, "s: %s", pr.outstr);
	    }

	  }
	} while ((pr=acapParse("")).result==MoreToCome);
      }
      if (pr.outstr) {
	fprintf(output, pr.outstr);
	if (LOG_SESSION) {
	  fprintf(session_dump, "s: %s", pr.outstr);
	}
      }
      if (pr.result==SessionDone)
	break;
    }
    else {
      lprintf(LOG_NOTICE, "Client sent line longer than %d characters",
	      MAX_LINE_LEN);
      fprintf(output, "* BAD \"Line too long (>%d characters)\"\r\n",
	      MAX_LINE_LEN);
      if (LOG_SESSION) {
	fprintf(session_dump,
		"s: * BAD \"Line too long (>%d characters)\"\r\n",
		MAX_LINE_LEN);
      }
      
      /* eat up the rest of the line */
      do
	fgets(buf, sizeof(buf), input);
      while (!containsCRLF(buf));
    }
  }

  lprintf(LOG_INFO, "Program ending");

  return 0;
}
