#include <iostream>
#include <string>
#include <cstring>
#include <ctime>

/**
   Convert human-readable date string to epoch seconds since 1/1/1970
*/
class HistoryCache
{
public:
  static std::string getTimeStamp(time_t epochTime, const char* format = "%Y-%m-%d %H:%M:%S %Z")
  {
    char timestamp[64] = {0};
    strftime(timestamp, sizeof(timestamp), format, localtime(&epochTime));
    return timestamp;
  }

  static time_t convertTimeToEpoch(const char* theTime, const char* format = "%Y-%m-%d %H:%M:%S %Z")
  {
    std::tm tmTime;
    memset(&tmTime, 0, sizeof(tmTime));
    strptime(theTime, format, &tmTime);
    return mktime(&tmTime);
  }
};


int main(int argc, char **argv)
{
 std:bool error = false;

  // Default timestring format
  const char *format = "%m/%d/%YT%H:%M:%S %Z";

  // Timestring is last argument
  for (int i = 1; i < argc-1; i++) {
    if (!strcmp(argv[i], "-format") && i < argc-2) {
      format = argv[++i];
    }
    else {
      error = true;
    }
  }

  if (argc == 1) {
    // No arguments - test with current time and default format
    // get current epoch time
    const time_t curTime = time(0);

    // convert current time to a string
    std::string curTimeStr = HistoryCache::getTimeStamp(curTime);

    // convert string time to an epoch time
    const time_t curTime2 = HistoryCache::convertTimeToEpoch(curTimeStr.c_str());

    // display results
    std::cout << "Epoch Time: " << curTime    << "\n"
	      << "As string : " << curTimeStr << "\n"
	      << "Epoch Time: " << curTime2
	      << std::endl;

    // Proceed to print out usage message and exit
    error = true;

  }

  if (argc < 2) error = true;

  if (error) {
    fprintf(stderr, 
	    "usage: %s [-format \"time format\"] \"timestring\"\n", argv[0]);
    fprintf(stderr, 
	    "default format is %%m/%%d/%%YT%%H:%%M:%%S\n");
    fprintf(stderr, 
	    "(see UNIX man page for strptime() for format definitions)\n");
    return 1;
  }

  // Timestring is always last argument
  char *timeString = argv[argc-1];

  // get current epoch time
  // const time_t curTime = time(0);

  // convert current time to a string
  // std::string curTimeStr = HistoryCache::getTimeStamp(curTime, format);

  // convert string time to an epoch time
  const time_t curTime2 = HistoryCache::convertTimeToEpoch(timeString,
							   format);
  printf("%ld\n", curTime2);

}
