#include "common.h"
#include "deal.h"


/* global variable that points to the main host table */
struct hostinfo *tablePtr;

/* is debugging on? */
extern int opt_debug;

/* add a host to the host table, check for duplicates */
int addhost(char address[MAXADDR], time_t ntime, int np){

  /* go through the table and check that the address is not already there */
  struct hostinfo *machinfo, *currPtr = tablePtr;
  while (currPtr != NULL) {
    if ((strcmp(currPtr->addr,address)) == 0){
      fprintf(stderr,"Duplicate address %s.\n",address);
      return(1);
    }
    else {
      currPtr = currPtr->nexthost;
    }
  }

  /* malloc space for a new entry in the table */
  machinfo = (struct hostinfo *) malloc(sizeof(struct hostinfo));
  if (machinfo == NULL){
    perror("malloc");
    return(-1);
  }
  else {
    /* put the new address and time in the malloc'd space, and point the 
     * entry's nexthost pointer to the beginning of the old table */ 
    strcpy(machinfo->addr,address);
    machinfo->time = ntime;
    machinfo->num_points = np;
    machinfo->nexthost = tablePtr;
  }

  /* change the table to point to the new entry */
  tablePtr = machinfo;
  return(0);
}


/* delete a host from the host table if it is there */
int delhost(char address[MAXADDR]) {
  int found = 1;
  struct hostinfo *freePtr, **lastPtr = &tablePtr;

  /* go through the table, and if you find a match, point the previous entry's
   * nexthost pointer to the following entry, then free the memory that 
   * contained the current entry */
  while (*lastPtr != NULL) {
    if ((strcmp((*lastPtr)->addr,address)) == 0) {
      freePtr = *lastPtr;
      *lastPtr = (*lastPtr)->nexthost;
      free(freePtr);

      /* set found to zero and stop looking through the table */
      found = 0;
      break;
    }
    lastPtr = &(*lastPtr)->nexthost;
  }

  /* return zero if the host is found, and one if it is not */
  return(found);
}


/* print a list that represents the current network state */
int list(int newsockfd) {
  int reply_len;
  char reply[MAXLINE] = "\0";
  struct hostinfo *currPtr = tablePtr;

  /* print header line */
  sprintf(reply, "200 Listing follows:\n");
  reply_len = strlen(reply);
  write(newsockfd,reply,reply_len);

  /* go through the host table and print out a line for every entry */
  while (currPtr != NULL) {
    sprintf(reply, "%s %d %d\n", currPtr->addr,(int) currPtr->time, currPtr->num_points);
    reply_len = strlen(reply);
    write(newsockfd,reply,reply_len);
    currPtr = currPtr->nexthost;
  }
  return(0);
}


/* print out all the changes since time stime */
int since(int newsockfd, time_t stime) {
  int reply_len;
  FILE *logPtr;
  char reply[MAXLINE] = "\0";
  char x[1], f[MAXADDR], s[MAXLINE];
  int *ftimePtr = malloc(sizeof(int));

  /* print the header line */
  sprintf(reply,"200 Changes since %i:\n",(int) stime);
  reply_len = strlen(reply);
  write(newsockfd,reply,reply_len);

  /* open the log file for reading */
  if ((logPtr = fopen(NLOG_FILE,"r")) == NULL) {
    perror("Error opening NLOG_FILE");
    exit(-1);
  }
 
  /* go through the log file and parse it */
  while (fgets(s,sizeof(s),logPtr) != NULL) {
    sscanf(s,"%s %s %d",x,f,ftimePtr);

    /* if the time the change was made is since stime, print out that line */
    if (stime <= *ftimePtr) {
      sprintf(reply, "%s",s);
      reply_len = strlen(reply);
      write(newsockfd,reply,reply_len);
    }
  }
  fclose(logPtr);
  return(0);
}
  

/* dump the current network state to the dump file */
int dump() {
  FILE *dumpPtr;
  int dumpfd;

  /* open the dump file to write */
  if ((dumpPtr = fopen(DUMP_FILE,"w")) == NULL) {
    perror("Couldn't open dump file");
    return (1);
  }
  dumpfd = fileno(dumpPtr);

  if (opt_debug) {
  fprintf(stderr,"Dumping list.\n");
  }

  /* do a list out to the dump file */
  if ((list(dumpfd)) != 0) {
    fprintf(stderr,"Error in dumping list.\n");
    return(1);
  }

  /* close the dump file */
  if((fclose(dumpPtr)) != 0) {
    perror("Couldn't close dump file");
    return(1);
  }
  return(0);
}

/* read a dump file and construct a host table from it */
int readdump() {
  FILE *dumpPtr;
  char line[MAXLINE];
  char addr[MAXADDR];
  int *np=malloc(sizeof(int)), *ptime=malloc(sizeof(int));
  
  /* open the dump file to read */
  if ((dumpPtr = fopen(DUMP_FILE,"r")) == NULL) {
    perror("Couldn't open dump file, continuing without it.");
    return(1);
  }

  /* get and throw away the header line */
  fgets(line,MAXLINE,dumpPtr);

  /* go through the rest of the file and add any hosts found */
  while((fgets(line,MAXLINE,dumpPtr)) != NULL) {
    sscanf(line,"%s %d %d",addr,ptime,np);
    addhost(addr,(time_t)*ptime,*np);
  }
  fclose(dumpPtr);
  return(0);
}


