#include "SquidLogFile.h"
#include <stdlib.h>
#include <string.h>

SquidLogFile::SquidLogFile()
{
  FP = NULL;
  isPipe = 0;
}


int SquidLogFile::open(const char* fname)
{
  if (strcmp(fname, "-") == 0)
    FP = stdin;
  else if (strcmp(fname + strlen(fname) - 3, ".gz") == 0)
    {
      char command[2000];
      strcpy(command, "gunzip -c ");
      strcat(command, fname);
      FP = popen(command, "r");
      isPipe = 1;
    }
  else
    FP = fopen(fname, "r");
  
  if (FP == NULL) return -1;
  else return 0;
}


int SquidLogFile::read(SquidRequest& req)
{
  char line[LINE_SIZE];

  // This is really ugly code.  The outer while is intended only to give
  // the continue somewhere to jump to.
  // All this is so that lines that are syntactically bad are discarded
  // transparently.
  while (1)
    {
      fgets(line, LINE_SIZE, FP);
      if (feof(FP))
	return 1;

      int ret = stringToRequest(line, req);
      if (ret != 0) 
	{
	  while (1)
	    {
	      char ch = fgetc(FP);
	      printf("Skipping %d=%c\n", ch, ch);
	      if (ch == '\n') break;
	    }
	  continue;
	}
      
      return 0;
    }
}


// Returns -1 if the line could not be parsed.  0 on success.
int SquidLogFile::stringToRequest(char* line, SquidRequest& req)
{
  // copy line into request structure
  memcpy(req.line, line, (req.lineSize>LINE_SIZE)?LINE_SIZE:req.lineSize);

  req.endTime = (long)(atof(strtok(line, " ")));
  
  req.client = atol(strtok(NULL, " "));

  req.processingTime = atol(strtok(NULL, " "));
  
  char* proxyResultText = strtok(NULL, "/");
  req.proxyResult = strcmp(proxyResultText, "TCP_HIT") == 0?SquidRequest::hit :
    strcmp(proxyResultText, "TCP_MISS") == 0? SquidRequest::miss :
    strcmp(proxyResultText, "TCP_REFRESH_HIT") == 0? SquidRequest::refreshHit :
    strcmp(proxyResultText, "TCP_REFRESH_MISS") == 0? SquidRequest::refreshMiss :
    strcmp(proxyResultText, "TCP_IMS_HIT") == 0? SquidRequest::imsHit :
    strcmp(proxyResultText, "TCP_IMS_MISS") == 0? SquidRequest::imsMiss :
    strcmp(proxyResultText, "TCP_CLIENT_REFRESH") == 0? SquidRequest::clientRefresh :
    strcmp(proxyResultText, "TCP_REF_FAIL_HIT") == 0? SquidRequest::refFailHit:
    SquidRequest::unknownProxyResult;

  req.httpResult = (SquidRequest::HttpResultCode)atol(strtok(NULL, " "));

  req.size = atol(strtok(NULL, " "));

  strtok(NULL, " ");   // Strip out GET

  char* url = strtok(NULL, " ");
  req.url[sizeof(req.url)-1] = 0;
  strncpy(req.url, url, sizeof(req.url)-1);

  strtok(NULL, " ");   // Strip out identity of user

  // Not sure what to do with these two fields, yet, but keep them.
  char *squidIcpResult = strtok(NULL, "/");
  char *squidIcpHost = strtok(NULL, " ");
  
  // Make sure we reached end of line.
  char *endOfLine = strtok(NULL, " ");
  if (endOfLine != NULL) return -1;

  return 0;
}


void SquidLogFile::close()
{
  // Return value of close is ignored.
  if (isPipe)
    pclose(FP);
  else 
    fclose(FP);

  FP = NULL;
}


SquidLogFile::~SquidLogFile()
{
  if (FP != NULL)
    {
      fprintf(stderr, "SquidLogFile deleted, but not closed.\n");
    }
}
