/* 
  WIDE AREA INFORMATION SERVER SOFTWARE:
   No guarantees or restrictions.  See the readme file for the full standard
   disclaimer.

   This is part of the shell user-interface tools for the WAIS software.
   Do with it as you please.

   Version 0.83
   Fri Jul 19 1991

   jonathan@Think.COM

*/

#define MAIN
#include "wais.h"

#define WAISQ_DATE "Fri Jul 19 1991"

char* log_file_name = NULL;
FILE* logfile = NULL;

/* this will take as its argument the name of a question file,
   and will do all the right things with it.
*/


usage(name) 
char *name;
{
  if (strstr(name, "waisq") != NULL) {
    fprintf(stderr,"Usage: waisq\n");
    fprintf(stderr,"  [-f question_file] /* defaults to stdin, stdout */\n");
    fprintf(stderr,"  [-s sourcedir] /* or environment variable WAISSOURCEDIR, or ~/wais-sources/ */\n");
    fprintf(stderr,"  [-S sourcename]\n");
    fprintf(stderr,"  [-c common_sourcedir] /* or environment variable WAISCOMMONSOURCEDIR */\n");
    fprintf(stderr,"  [-v document_number]\n");
    fprintf(stderr,"  [-g]	/* to do a search */\n");
    fprintf(stderr,"  [-h]	/* this message */\n");
    fprintf(stderr,"  [-t]	/* test a source */\n");
    fprintf(stderr,"  [-V]	/* print version */\n");
    fprintf(stderr,"  [word [word [...]]]\n");
    fprintf(stderr,"or %s -	/* interactive mode */\n", name);
  }
  else {
    fprintf(stderr,"Usage: waisping\n");
    fprintf(stderr,"  [-s sourcedir] /* or environment variable WAISSOURCEDIR, or ~/wais-sources/ */\n");
    fprintf(stderr,"  [-c common_sourcedir] /* or environment variable WAISCOMMONSOURCEDIR */\n");
    fprintf(stderr,"  sourcename\n");
  }
}

void SetSource(question, sourcename)
Question question;
char *sourcename;
{
  SourceList s;
  SourceID sid;

  sid = (SourceID)s_malloc(sizeof(_SourceID));
  s = (SourceList)s_malloc(sizeof(_SourceList));
  s->thisSource = sid;
  s->nextSource = NULL;
  sid->filename = sourcename;
  question->Sources = s;
}

char *
fixdirname(dir)
char *dir;
{
  char *res;

  if(dir[strlen(dir)-1] == '/') res = dir;
  else {
    res = s_malloc(strlen(dir)+2);
    sprintf(res,"%s/", dir);
  }
  return res;
}

void update_source_connections(s,d)
SList s, d;
{
  SList t1, t2;

  for(t1 = s; t1 != NULL; t1 = t1->nextSource) {
    for (t2 = d; t2 != NULL; t2 = t2->nextSource) {
      if (strcmp(t1->thisSource->server, t2->thisSource->server) == 0 &&
	  strcmp(t1->thisSource->service, t2->thisSource->service) == 0 &&
	  t1->thisSource->connection != NULL) {
	t2->thisSource->connection = t1->thisSource->connection;
	t2->thisSource->buffer_length = t1->thisSource->buffer_length;
	t2->thisSource->initp = t1->thisSource->initp;
	if (strcmp(t1->thisSource->name, "ReMoVe") != 0) {
	  s_free(t1->thisSource->name);
	  t1->thisSource->name = s_strdup("ReMoVe");
	}
      }
    }
    if (strcmp(t1->thisSource->name, "ReMoVe") != 0 &&
	t1->thisSource->connection != NULL) {
      close_connection_to_server(t1->thisSource->connection);
      for (t2 = t1->nextSource; t2 != NULL; t2 = t2->nextSource) {
	if (strcmp(t1->thisSource->server, t2->thisSource->server) == 0 &&
	    strcmp(t1->thisSource->service, t2->thisSource->service) == 0)
	  t2->thisSource->connection = NULL;
      }
    }
  }
}

void
main(argc, argv)
     int argc;
     char *argv[];
{
  Question question;
  char msg[STRINGSIZE];
  char *sdir, *cdir, *qfilename, *sourcename, *getenv();
  char keywords[STRINGSIZE];
  int i, document_number;
  Boolean dosearch, interactive_mode, test_mode;
  FILE *fp;

  sdir = cdir = qfilename = sourcename = NULL;
  keywords[0] = 0;
  document_number = -1;
  dosearch = interactive_mode = test_mode = FALSE;

  NumSources = 0;

  if(strstr(argv[0], "waisping") != NULL) test_mode = TRUE;

  /* parse arguments */

  if (argc == 1) {
    usage(argv[0]);
    exit(0);
  }

  /* if the first arg is '-', do interactive mode */

  i = 1;

  if((argv[1][0] == '-') && (argv[1][1] == 0)) {
    interactive_mode = TRUE;
    i++;
  }
  for(; i < argc; i++) {
    if (*argv[i] == '-') {
      argv[i]++;
      switch (*argv[i]) {
      case 'f':
	i++;
	if(i >= argc) {
	  fprintf(stderr, "Too few arguments: file name missing.\n");
	  exit(1);
	  }
	qfilename = argv[i];
	break;
      case 'c':
	i++;
	if(i >= argc) {
	  fprintf(stderr, "Too few arguments: source directory missing.\n");
	  exit(1);
	  }
	cdir = argv[i];
	break;
      case 's':
	i++;
	if(i >= argc) {
	  fprintf(stderr, "Too few arguments: source directory missing.\n");
	  exit(1);
	  }
	sdir = argv[i];
	break;
      case 'S':
	i++;
	if(i >= argc) {
	  fprintf(stderr, "Too few arguments: source name missing.\n");
	  exit(1);
	  }
	sourcename = argv[i];
	break;
      case 'v':
	i++;
	if(i >= argc) {
	  fprintf(stderr, "Too few arguments: Document number missing.\n");
	  exit(1);
	  }
	document_number = atoi(argv[i]);
	break;
      case 'g':
	dosearch = TRUE;
	break;
      case 'h':
	usage(argv[0]);
	exit(0);
	break;
      case 't':
	test_mode = TRUE;
	break;
      case 'V':
	printf("%s version: %s, %s.\n", argv[0], VERSION, WAISQ_DATE);
	exit(0);
      default:
	fprintf(stderr, "Unknown option: %s.\n", argv[i]);
	exit(1);
      }
    }
    else {
      if(test_mode)
	strcpy(keywords, argv[i]);
      else if((strlen(keywords) + strlen(argv[i]) + 1) < STRINGSIZE) {
	strcat(keywords, argv[i]);
	strcat(keywords, " ");
      }
    }
  }
      
  if(sdir == NULL) {
    if((sdir = getenv("WAISSOURCEDIR")) == NULL) {
      sprintf(msg, "%s/wais-sources/", getenv("HOME"));
      sdir = s_strdup(msg);
    }
  }

  if(cdir == NULL) cdir = getenv("WAISCOMMONSOURCEDIR");

  sdir = fixdirname(sdir);
  ReadSourceDirectory(sdir, TRUE);

  if(cdir != NULL) {
    cdir = fixdirname(cdir);
    ReadSourceDirectory(cdir, TRUE);
  }

  the_Question = (Question)s_malloc(sizeof(_Question));

  if(test_mode) {

    question = the_Question;

    SetSource(question, keywords);

    test_connection(question);
    exit(0);
  }

  if(!interactive_mode) {
    if (qfilename != NULL) {
      if(strcmp(qfilename, "-")) {
	if((fp = fopen(qfilename, "r")) == NULL) {
	  fprintf(stderr, "Can't open question %s\n", qfilename);
	  exit(-1);
	}
	ReadQuestion(the_Question, fp);
	fclose(fp);
      }
    }
    else {
      fp = stdin;
      ReadQuestion(the_Question, fp);
    }

    question = the_Question;

    question->modified = TRUE;

    question->numsources =
      listlength((List)question->Sources);

    question->numdocs =
      listlength((List)question->RelevantDocuments);

    question->numresdocs =
      listlength((List)question->ResultDocuments);

    if (keywords[0] != 0) {
      strcpy(question->keywords,keywords);
    }

    if (sourcename != NULL) {
      SetSource(question, sourcename);
    }

    if(dosearch == TRUE) {
      SearchWais(question);
      if((qfilename == NULL) || (strcmp(qfilename, "-") == 0))
	WriteQuestionfp(stdout, question);
      else
	WriteQuestion(qfilename, question);
    }
    else if(strcmp(qfilename, "-") == 0)
      WriteQuestionfp(stdout, question);

    if((document_number > 0) && (document_number <= question->numresdocs)) {	/* view a document */
      DocumentID doc;
      
      if((doc = findDoc(question->ResultDocuments, document_number-1))
	 == NULL) {
	PrintStatus("Unable to find document.  This should not happen.\n");
	return;
      }
      ViewWaisDocument(question, doc);
    }
  }
  else {
    /* interactive mode!
       read questions from standard in, write to stdout, until an empty question comes through.
       */
    question = the_Question;
    while(interactive_mode) {
      SList current_sources;

      /* clear stuff */
      question->Sources = NULL;
      question->RelevantDocuments = NULL;
      question->ResultDocuments = NULL;
      strcpy(question->keywords, "");
      current_sources = Sources;
      Sources = NULL;
      if(ReadQuestion(question, stdin)) {
	/* reread sources */

	ReadSourceDirectory(sdir, TRUE);
	if(cdir != NULL)
	  ReadSourceDirectory(cdir, TRUE);

	update_source_connections(current_sources,Sources);
	
	FreeSources(current_sources);

	question->modified = TRUE;
	question->numsources =
	  listlength((List)question->Sources);
	question->numdocs =
	  listlength((List)question->RelevantDocuments);
	question->numresdocs =
	  listlength((List)question->ResultDocuments);

	/* cases */
	if((strlen(question->keywords) != 0) ||
	   (question->numdocs > 0)) {
	  SearchWais(question);
	  WriteQuestionfp(stdout, question);
	}
	else if(question->numresdocs > 0)
	  for(i = 0; i < question->numresdocs; i++) {
	    ViewWaisDocument(question, findDoc(question->ResultDocuments, i));
	  }
	else {
	  SearchWais(question);
	  WriteQuestionfp(stdout, question);
	}
	fprintf(stdout, "Waisq: Ready for next question.\n");
	fflush(stdout);
      }
      else interactive_mode = FALSE;
    }
  }
}
