/* 
 * Starter for WordGame (Homework 1X, part 3)
 *
 */

/*
 * 
 * Do not modify this awful C code
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "WordGameInterface.h"

#define HUGEBUFSIZE 4096

/* #define DEBUG */

/* Memory is cheap */
static char bigLineBuff[HUGEBUFSIZE+1] ;
static char bigKeyBuff[HUGEBUFSIZE+1] ;
static char bigValueBuff[HUGEBUFSIZE+1] ;

int main(int argc, char** argv) {

  char *mapFN, *inFN, *outFN ;
  FILE *mapFH, *inFH, *outFH ;
  int badFiles = 0 ;
  void * GameInterface ;
  int nextChar ;
  int readingKey ;
  int keyPos ;

  if (argc != 4) {
    puts("Wrong number of arguments") ;
    return EXIT_FAILURE ;
  }
  mapFN = argv[1] ;
  inFN  = argv[2] ;
  outFN = argv[3] ;
  
  if ((mapFH = fopen(mapFN, "r")) == NULL) {
    printf("Unable to open map file %s\n", mapFN) ;
    badFiles = 1 ;
  } 
  if ((inFH = fopen(inFN, "r")) == NULL) {
    printf("Unable to open input file %s\n", inFN) ;
    badFiles = 1 ;
  }
  if ((outFH = fopen(outFN, "w")) == NULL) {
    printf("Unable to open output file %s\n", outFN) ;
    badFiles = 1 ;
  }

  if (badFiles) {
    return EXIT_FAILURE ;
  }

  GameInterface = CreateWGI() ;

  /* Read the word map file and add key,value pairs to the word map */
  while (fgets(bigLineBuff, HUGEBUFSIZE, mapFH) != NULL) {
    const char BadLineFormat[] = "Bad line %s in %s\n" ;
    int keyStart ;                         /* start of key */
    int linePtr ;                          /* Current position within line */
    int dstPos, srcPos ;                   /* pointers for copying */
#ifdef DEBUG    
    printf(">line is %s", bigLineBuff) ;
#endif

    /* This is so ugly ..... */
    bigLineBuff[HUGEBUFSIZE] = '\0' ;        /* for huge lines */

    /* Find the key */
    linePtr = 0 ;
    while (bigLineBuff[linePtr] != '\0' && bigLineBuff[linePtr] != '*') {
      ++linePtr ;
    }
    if (bigLineBuff[linePtr] == '\0') {
      printf(BadLineFormat, bigLineBuff, mapFN) ;
      return EXIT_FAILURE ;
    }
    ++linePtr ;
    keyStart = linePtr ;
    while (bigLineBuff[linePtr] != '\0' && bigLineBuff[linePtr] != '*') {
      ++linePtr ;
    }
    if (bigLineBuff[linePtr] == '\0') {
      printf(BadLineFormat, bigLineBuff, mapFN) ;
      return EXIT_FAILURE ;
    }
    /* Copy the key to the KeyBuff */
    for (dstPos=0, srcPos=keyStart;
	 srcPos < linePtr ;
	 ++dstPos, ++srcPos) {
      bigKeyBuff[dstPos] = bigLineBuff[srcPos] ;
    }
    bigKeyBuff[dstPos] = '\0' ;
#ifdef DEBUG    
    printf(">key is %s\n", bigKeyBuff) ;
#endif

    /* Find the end of the operator -- just looking for = */
    while (bigLineBuff[linePtr] != '\0' && bigLineBuff[linePtr] != '=') {
      ++linePtr ;
    }
    if (bigLineBuff[linePtr] == '\0') {
      printf(BadLineFormat, bigLineBuff, mapFN) ;
      return EXIT_FAILURE ;
    }

    linePtr++;
    /* Now find the various values */
    while (bigLineBuff[linePtr] != '\0' && isspace(bigLineBuff[linePtr])) {
      linePtr++;
    }
    while (bigLineBuff[linePtr] != '\0') {
      int firstNonBlank, lastNonBlank ;
      lastNonBlank = firstNonBlank = linePtr ;
      while (bigLineBuff[linePtr] != '\0'
	     && bigLineBuff[linePtr] != ','
	     && bigLineBuff[linePtr] != '\n'
	     ) {
	if (!isspace((int)bigLineBuff[linePtr])) {
	  lastNonBlank = linePtr ;
	}
	++linePtr ;
      }
      if (bigLineBuff[linePtr] == '\0') {
	printf(BadLineFormat, bigLineBuff, mapFN) ;
	return EXIT_FAILURE ;
      }
      /* Copy the value to  bigValueBuff */
      for (dstPos=0, srcPos=firstNonBlank ;
	   srcPos <= lastNonBlank;
	   ++dstPos, ++srcPos) {
	bigValueBuff[dstPos] = bigLineBuff[srcPos] ;
      }
      bigValueBuff[dstPos] = '\0' ;
#ifdef DEBUG    
      printf(">(key,value) is (%s,%s)\n", bigKeyBuff, bigValueBuff) ;
#endif
      AddWordToKeyWGI(GameInterface, bigValueBuff, bigKeyBuff) ;
      linePtr++ ;
      while (bigLineBuff[linePtr] != '\0' && isspace(bigLineBuff[linePtr])) {
	linePtr++;
      }
    }
  }
  fclose(mapFH) ;

  /* Read the input file and write the output file */
  readingKey = 0 ;
  while ((nextChar = fgetc(inFH)) != EOF) {
    if (readingKey) {
      if (nextChar == '*') {
	const char *value ;
	bigKeyBuff[keyPos] = '\0' ;
	value = LookupNextWordWGI(GameInterface, bigKeyBuff) ;
#ifdef DEBUG
	printf("\n>Input key is %s\n", bigKeyBuff) ;
	printf("\n>Output value is %s\n", value) ;
#endif
	if (value == NULL) {
	  value = "*??*" ;
	}
	fputs(value, outFH) ;
	readingKey = 0 ;
      } else {
	bigKeyBuff[keyPos] = (char) nextChar ;
	++keyPos ;
      }
    } else {
      if (nextChar == '*') {
	keyPos = 0 ;
	readingKey = 1 ;
      } else {
#ifdef DEBUG
	putchar(nextChar) ;
#endif
	fputc(nextChar, outFH) ;
      }
    }
  }
  fclose(inFH) ;
  fclose(outFH) ;
}
