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

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

int DecLogFile::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;

  // Strip 8K header.
  int i;
  char ch;
  for (i = 0; i < 8192; i++)
    {
      fread(&ch, 1, 1, FP);
    }

  return 0;
}


int DecLogFile::read(DecRequest& req)
{
  TEntry_v2 entry;

  int bytesread = 0;

  while (bytesread < sizeof(entry))
    {
      int thisBytesread = fread(((char*)&entry) + bytesread, /*sizeof(entry) - bytesread*/1, 1, FP);
      // printf("%x \n", *(((char*)&entry) + bytesread));
      bytesread += thisBytesread;
      //      printf("thisBytesread = %d\n", thisBytesread);

      if (thisBytesread == 0)
	{
	  if (feof(FP))
	    return 1;
	  else
	    return -1;
	}
    }

  // copy request to field in request struct
  memcpy(&(req.entry), &entry, sizeof(TEntry_v2));

#if defined(__sparc__)
  lsbToMsb(entry.time_sec);
  lsbToMsb(entry.event_duration);
  lsbToMsb(entry.size);
  lsbToMsb(entry.last_mod);
  lsbToMsb(entry.server);
  lsbToMsb(entry.port);
  lsbToMsb(entry.path);
  lsbToMsb(entry.query);
  lsbToMsb(entry.client);
  lsbToMsb(entry.status);
#endif  

  req.startTime = entry.time_sec;
  req.processingTime = entry.event_duration;
  req.size = entry.size;
  req.lastModified = entry.last_mod;
  req.urlHash = entry.server ^ 
                (entry.port << 8) ^ (entry.port >> 24) ^
                (entry.path << 16) ^ (entry.path >> 16) ^
                (entry.query << 24) ^ (entry.query >> 8);
  req.client = entry.client;
  req.httpResult = (DecRequest::HttpResultCode)entry.status;

  return 0;
}


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

  FP = NULL;
}


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


inline void DecLogFile::lsbToMsb(u_4bytes& n)
{
  n = (n >> 24) | ((n >> 8) & 0xFF00) | ((n << 8) & 0xFF0000) | (n << 24);
}


inline void DecLogFile::lsbToMsb(unsigned short& n)
{
  n = (n >> 8) | (n << 8);
}


