//=-- AccessFormatPlugin.cpp - This base class decodes accesses ---------------=
//
//   This class is used to handle one line out of the access_log file.
//
//=----------------------------------------------------------------------------=
//  This file is copyright (c) 1997-2000 Chris Lattner
//=----------------------------------------------------------------------------=

#include "AccessFormatPlugin.h"
#include "Date.h"

const String &AccessFormatPlugin::GetField(int FieldNo) const {
  switch (FieldNo) {
  case FEHost:        return GetHost();
  case FEAuth:        return GetAuth();
  case FEType:        return GetRetType();
  case FEProtocol:    return GetProtocol();
  case FEReferrer:    return GetReferrer();
  case FEBrowser:     return GetBrowser();

  case FEDate:
  case FEStatus:
  case FESize:
  default:
  case FEURL:
    return GetURL();
  }  
}

void AccessFormatPlugin::SetField(int FieldNo, const String &FieldVal) {
  switch (FieldNo) {
  case FEHost:        GetHost() = FieldVal; break;
  case FEAuth:        GetAuth() = FieldVal; break;
  case FEType:        GetRetType() = FieldVal; break;
  case FEProtocol:    GetProtocol() = FieldVal; break;
  case FEReferrer:    GetReferrer() = FieldVal; break;
  case FEBrowser:     GetBrowser() = FieldVal; break;

  case FEDate:
  case FEStatus:
  case FESize:
  default:
  case FEURL:
    GetURL() = FieldVal; break;
  }  
}



// Could be made faster by making strings static or by using
// strcmp on raw string...
//
int AccessFormatPlugin::GetFieldID(const CSString &FieldName) {
  switch (FieldName.Length()) {
  case 3:
    if (FieldName == CSString("URL")) return FEURL;
    break;

  case 4:
    if (FieldName == CSString("HOST")) return FEHost;
    if (FieldName == CSString("TYPE")) return FEType;
    if (FieldName == CSString("Date")) return FEDate;
    if (FieldName == CSString("Size")) return FESize;
    if (FieldName == CSString("Auth")) return FEAuth;
    break;
  
  case 6:
    if (FieldName == CSString("Status")) return FEStatus;
    break;

  case 7:
    if (FieldName == CSString("BROWSER")) return FEBrowser;
    break;

  case 8:
    if (FieldName == CSString("PROTOCOL")) return FEProtocol;
    if (FieldName == CSString("REFERRER")) return FEReferrer;
    break;

  }

  return FEURL;
}

int AccessFormatPlugin::Compare(const Object &AO) const {
  AccessFormatPlugin &A = (AccessFormatPlugin &)AO;

  if (GetHost() != A.GetHost() || GetAuth() != A.GetAuth() || 
      GetDate() != A.GetDate() || GetType() != A.GetType() || 
      GetURL()  != A.GetURL() || GetProtocol() != A.GetProtocol() || 
      GetStatusCode() != A.GetStatusCode() || GetLength() != A.GetLength() ||
      GetBrowser() != A.GetBrowser() || GetReferrer() != A.GetReferrer())
      return 1;
  return 0;
}

// Pareses a date HTTP date field into a date object. 
//   Example of a date field: "29/Jul/1997:21:15:23 -0800"
int AccessFormatPlugin::ParseDateString(String &TimeBuffer) {
  String Tok, Month, TimeZone;
  int Day;
  Date &D = GetDate();

  TimeBuffer.Tokenize("/", Tok);
  Day = Tok.atoi();

  TimeBuffer.Tokenize("/", Month);
  TimeBuffer.Tokenize(":", Tok);
  int Year = Tok.atoi();
  if (Year < 300) Year += 1900;
  if (Year < 1971 || Year > 2030)   // Do some date checking...
    return -1;

  D = Date(Day, Date::GetMonthNumber(Month), Year);

  TimeBuffer.Tokenize(":", Tok);
  D.SetHour(Tok.atoi());
  TimeBuffer.Tokenize(":", Tok);
  D.SetMinute(Tok.atoi());
  TimeBuffer.Tokenize(" ", Tok);
  D.SetSecond(Tok.atoi());

  TimeZone = TimeBuffer;
  // Offset stuff by TimeZone
  return 0;
}

ostream &AccessFormatPlugin::print(ostream &o) const {
  o << "Host: "              << GetHost()          << endl;
  o << "Username/Password: " << GetAuth()          << endl;
  o << "Date: "              << GetDate()          << endl;
  o << "RetrievalType: "     << GetRetType()       << endl;
  o << "URL: "               << GetURL()           << endl;
  o << "Protocol: "          << GetProtocol()      << endl;
  o << "Status code: "       << GetStatusCode()    << endl;
  o << "File length: "       << GetLength()        << endl;

  if (GetReferrer().Length())
    o << "Referrer: "        << GetReferrer()      << endl;
  if (GetBrowser().Length())
    o << "Browser: "         << GetBrowser()       << endl;

  o << "AccessLog Filename: "<< GetAccessLogFilename() << endl;
  return o;
}
