#include <pop.h>
#include <stdio.h>

static PopServer server = 0;
static int mark_from = 0;

#ifdef __STDC__
#define DECLARE(f) /*ARGSUSED*/f(int argc, const char * const * argv, void *sci_idx)
#else
#define DECLARE(f) /*ARGSUSED*/f(argc, argv, sci_idx) int argc; char **argv; char *sci_idx;
#endif /* __STDC__ */

DECLARE(popper_connect)
{
     int i;
     char *host = 0, *user = 0, *password = 0;

     if (server) {
	  fprintf(stderr, "Already connected.\n");
	  return;
     }

     for (i = 1; i < argc; i++) {
	  if (0 == strcmp(argv[i], "-host")) {
	       if (i == argc - 1) {
		    fprintf(stderr, "Missing argument to -host\n");
		    return;
	       }
	       host = (char *) argv[++i];
	  }
	  else if (0 == strcmp(argv[i], "-user")) {
	       if (i == argc - 1) {
		    fprintf(stderr, "Missing argument to -user\n");
		    return;
	       }
	       user = (char *) argv[++i];
	  }
	  else if (0 == strcmp(argv[i], "-password")) {
	       if (i == argc - 1) {
		    fprintf(stderr, "Missing argument to -password\n");
		    return;
	       }
	       password = (char *) argv[++i];
	  }
	  else {
	       fprintf(stderr, "Unknown argument %s\n", argv[i]);
	       fprintf(stderr, "Usage: %s [ -host host ] [ -user user ] [ -password password ]\n", argv[0]);
	       return;
	  }
     }

     if (! (server = pop_open(host, user, password, 0))) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }
}

DECLARE(popper_stat)
{
     int count, size;

     if (argc > 1) {
	  fprintf(stderr, "Too many arguments.\n");
	  fprintf(stderr, "Usage: %s\n", argv[0]);
	  return;
     }

     if (! server) {
	  fprintf(stderr, "Not connected.\n");
	  return;
     }

     if (pop_stat(server, &count, &size)) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     printf("%d messages, %d bytes.\n", count, size);
}

DECLARE(popper_list)
{
     int *IDs, *sizes;
     int message = 0;
     int i;
     
     if (! server) {
	  fprintf(stderr, "Not connected.\n");
	  return;
     }

     if (argc == 2) {
	  message = atoi(argv[1]);
	  if (! message) {
	       fprintf(stderr, "%s is not a valid message number.\n", argv[1]);
	       goto usage;
	  }
     }
     else if (argc != 1) {
	  goto usage;
     }

     if (pop_list(server, message, &IDs, &sizes)) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     printf("message\tsize\n");

     for (i = 0; IDs[i]; i++) {
	  printf("%d\t%d\n", IDs[i], sizes[i]);
     }

     free(IDs);
     free(sizes);
     return;

usage:
     fprintf(stderr, "Usage: %s [ message ]\n", argv[0]);
     return;
}

DECLARE(popper_retrieve)
{
     int message;
     char *line;
     int ret, in_body = 0;

     if (! server) {
	  fprintf(stderr, "Not connected.\n");
	  return;
     }

     if (argc != 2) {
	  goto usage;
     }

     message = atoi(argv[1]);
     if (! message) {
	  fprintf(stderr, "%s is not a valid message number.\n", argv[1]);
	  goto usage;
     }

     if (pop_retrieve_first(server, message, &line)) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     while (0 == (ret = pop_retrieve_next(server, &line))) {
	  if (! line) {
	       break;
	  }
	  else if (! *line) {
	       in_body++;
	  }
	  printf("%s%s\n",
		 (mark_from && in_body && (0 == strncmp(line, "From ", 5)))
		 ? ">" : "", line);
     }

     if (ret) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     return;

usage:
     fprintf(stderr, "Usage: %s message\n", argv[0]);
     return;
}

DECLARE(popper_top)
{
     int message, lines = 0, ret, in_body = 0;
     char *line;

     if (! server) {
	  fprintf(stderr, "Not connected.\n");
     }

     if (argc == 3) {
	  lines = atoi(argv[2]);
	  if (! lines) {
	       fprintf(stderr, "%s is not a valid number of lines.\n",
		       argv[2]);
	       goto usage;
	  }
     }

     if ((argc == 2) || (argc == 3)) {
	  message = atoi(argv[1]);
	  if (! message) {
	       fprintf(stderr, "%s is not a valid message number.\n", argv[1]);
	       goto usage;
	  }
     }
     else {
	  goto usage;
     }

     if (pop_top_first(server, message, lines, &line)) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     while (! (ret = pop_top_next(server, &line))) {
	  if (! line) {
	       break;
	  }
	  else if (! *line) {
	       in_body++;
	  }
	  printf("%s%s\n",
		 (mark_from && in_body && (0 == strncmp(line, "From ", 5)))
		 ? ">" : "", line);
     }

     if (ret) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     return;

usage:
     fprintf(stderr, "Usage: %s message [ lines ]\n", argv[0]);
     return;
}

DECLARE(popper_mark_from)
{
     if (argc != 1) {
	  fprintf(stderr, "Usage: %s\n", argv[0]);
	  return;
     }

     mark_from = !mark_from;

     printf("Marking of `From' lines is now %s.\n", mark_from ? "on" : "off");
     return;
}

DECLARE(popper_debug)
{
     if (argc != 1) {
	  fprintf(stderr, "Usage: %s\n", argv[0]);
	  return;
     }
     
     pop_debug = !pop_debug;

     printf("POP debugging is now %s.\n", pop_debug ? "on" : "off");
     return;
}

DECLARE(popper_delete)
{
     int message;

     if (! server) {
	  fprintf(stderr, "Not connected.\n");
	  return;
     }

     if (argc != 2) {
	  goto usage;
     }

     message = atoi(argv[1]);
     if (! message) {
	  fprintf(stderr, "%s is not a valid message number.\n", argv[1]);
	  goto usage;
     }

     if (pop_delete(server, message)) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     return;

usage:
     fprintf(stderr, "Usage: %s message\n", argv[0]);
     return;
}

DECLARE(popper_noop)
{
     if (! server) {
	  fprintf(stderr, "Not connected.\n");
	  return;
     }

     if (argc > 1) {
	  fprintf(stderr, "Usage: %s\n", argv[0]);
	  return;
     }

     if (pop_noop(server)) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     return;
}

DECLARE(popper_last)
{
     int last;

     if (! server) {
	  fprintf(stderr, "Not connected.\n");
     }

     if (argc > 1) {
	  fprintf(stderr, "Usage: %s\n", argv[0]);
	  return;
     }

     if ((last = pop_last(server)) < 0) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     printf("%d\n", last);
     return;
}

DECLARE(popper_reset)
{
     if (! server) {
	  fprintf(stderr, "Not connected.\n");
	  return;
     }

     if (argc > 1) {
	  fprintf(stderr, "Usage: %s\n", argv[0]);
	  return;
     }

     if (pop_reset(server)) {
	  fprintf(stderr, "%s\n", pop_error);
	  return;
     }

     return;
}

DECLARE(popper_quit)
{
     if (argc > 1) {
	  fprintf(stderr, "Usage: %s\n", argv[0]);
	  return;
     }

     if (server && pop_quit(server)) {
	  fprintf(stderr, "%s\n", pop_error);
     }

     exit(0);
}

DECLARE(popper_exit)
{
     if (server) {
	  pop_close(server);
     }
     exit(0);
}
