/**
 *
 * Copyright (C) 2014 University of Arizona.
 * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
 *
 */

#include <sstream>
#include <boost/asio.hpp>
#include <boost/filesystem.hpp>

#include <ndn-cpp-dev/face.hpp>
#include <ndn-cpp-dev/security/key-chain.hpp>

using namespace ndn;

class Logger
{
public:

  Logger()
  {
    logLocation_ = "";
  }

  void
  shutdownLogger()
  {
    if (logFile_.is_open())
    {
      log("Terminating Logging Operations" , true, true);
      logFile_.close();
    }
  }

  static std::string
  getTimestamp()
  {
    boost::posix_time::ptime now;
    now = boost::posix_time::second_clock::local_time();
    return to_simple_string(now);
  }

  void
  log( std::string logLine, bool printTime, bool printToConsole )
  {
    if( logLocation_.length() > 0 )
    {
      if (printTime)
        logFile_ << getTimestamp() << " - ";
      logFile_ << logLine << std::endl;
      logFile_.flush();
      if (printToConsole)
      {
        if (printTime)
          std::cout << getTimestamp() << " - ";
        std::cout << logLine << std::endl;
      }
    }
    else
    {
      if (printTime)
        std::cout << getTimestamp() << " - ";
      std::cout << logLine << std::endl;
    }
  }

  void
  initializeLog( std::string instanceId )
  {
    char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");
    std::string logFilename;
    logLocation_ = "";
    if (variableValue != NULL)
      logLocation_ = variableValue;
    if (boost::filesystem::exists(boost::filesystem::path(logLocation_)))
    {
      if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_)))
      {
        logFilename = logLocation_+"/NDNTrafficServer_"+instanceId+".log";
        logFile_.open(logFilename.c_str(), std::ofstream::out | std::ofstream::trunc);
        if (logFile_.is_open())
          std::cout << "Log File Initialized: " << logFilename << std::endl;
        else
        {
          std::cout << "ERROR - Unable To Initialize A Log File At: " << logLocation_ << std::endl
                    << "Using Default Output For Logging." << std::endl;
          logLocation_ = "";
        }
      }
      else
      {
        std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder." << std::endl
                  << "Using Default Output For Logging." << std::endl;
        logLocation_ = "";
      }
    }
    else
    {
      std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set." << std::endl
                << "Using Default Output For Logging." << std::endl;
      logLocation_ = "";
    }
  }

private:

  std::string logLocation_;
  std::ofstream logFile_;

};


class NdnTrafficServer
{
public:

  NdnTrafficServer( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_), keyChain_()
  {
    std::srand(std::time(0));
    instanceId_ = toString(std::rand());
    programName_ = programName;
    contentDelayTime_ = getDefaultContentDelayTime();
    totalRegistrationsFailed_ = 0;
    configurationFile_ = "";
    totalInterestReceived_ = 0;
  }

  class DataTrafficConfiguration
  {
  public:

    DataTrafficConfiguration()
    {
      name = "";
      contentType = -1;
      freshnessPeriod = -1;
      contentBytes = -1;
      content = "";
      totalInterestReceived = 0;
    }

    void
    printTrafficConfiguration( Logger& logger )
    {
      std::string detail;
      detail = "";
      if (name != "")
        detail += "Name="+name+", ";
      if (contentType >= 0)
        detail += "ContentType="+toString(contentType)+", ";
      if (freshnessPeriod >= 0)
        detail += "FreshnessPeriod="+toString(freshnessPeriod)+", ";
      if (contentBytes >= 0)
        detail += "ContentBytes="+toString(contentBytes)+", ";
      if (content != "")
        detail += "Content="+content+", ";
      if (detail.length() >= 0)
        detail = detail.substr(0, detail.length()-2);
      logger.log(detail, false, false);
    }


    bool
    extractParameterValue( std::string detail, std::string& parameter, std::string& value )
    {
      int i;
      std::string allowedCharacters = ":/+._-%";
      parameter = "";
      value = "";
      i = 0;
      while (detail[i] != '=' && i < detail.length())
      {
        parameter += detail[i];
        i++;
      }
      if (i == detail.length())
        return false;
      i++;
      while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length())
      {
        value += detail[i];
        i++;
      }
      if(parameter == "" || value == "")
        return false;
      return true;
    }

    bool
    processConfigurationDetail( std::string detail, Logger& logger, int lineNumber )
    {
      std::string parameter, value;
      if (extractParameterValue(detail, parameter, value))
      {
        if (parameter == "Name")
          name = value;
        else if (parameter == "ContentType")
          contentType = toInteger(value);
        else if (parameter == "FreshnessPeriod")
          freshnessPeriod = toInteger(value);
        else if (parameter == "ContentBytes")
          contentBytes = toInteger(value);
        else if (parameter == "Content")
          content = value;
        else
          logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true);
      }
      else
      {
        logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true);
        return false;
      }
      return true;
    }

    bool
    checkTrafficDetailCorrectness()
    {
      return true;
    }

    std::string name;
    int contentType;
    int freshnessPeriod;
    int contentBytes;
    std::string content;
    int totalInterestReceived;

  };

  std::string
  getDefaultContent()
  {
    return "";
  }

  static std::string
  toString( int integerValue )
  {
    std::stringstream stream;
    stream << integerValue;
    return stream.str();
  }

  static int
  toInteger( std::string stringValue )
  {
    int integerValue;
    std::stringstream stream(stringValue);
    stream >> integerValue;
    return integerValue;
  }

  void
  usage()
  {

    std::cout << "\nUsage: " << programName_ << " [options] <Traffic_Configuration_File>\n"
        "Respond to Interest as per provided Traffic Configuration File\n"
        "Multiple Prefixes can be configured for handling.\n"
        "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
        "  [-d interval] - set delay before responding to interest in milliseconds (minimum "
        << getDefaultContentDelayTime() << " milliseconds)\n"
        "  [-h] - print help and exit\n\n";
    exit(1);

  }

  int
  getDefaultContentDelayTime()
  {
    return 0;
  }

  void
  setContentDelayTime( int contentDelayTime )
  {
    if (contentDelayTime < 0)
      usage();
    contentDelayTime_ = contentDelayTime;
  }

  void
  setConfigurationFile( char* configurationFile )
  {
    configurationFile_ = configurationFile;
  }

  void
  signalHandler()
  {
    logger_.shutdownLogger();
    face_.shutdown();
    ioService_.reset();
    logStatistics();
    exit(1);
  }

  void
  logStatistics()
  {
    int patternId;
    logger_.log("\n\n== Interest Traffic Report ==\n", false, true);
    logger_.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);
    logger_.log("Total Interests Received    = "+toString(totalInterestReceived_), false, true);
    for (patternId=0; patternId<trafficPattern_.size(); patternId++)
    {
      logger_.log("\nTraffic Pattern Type #"+toString(patternId+1), false, true);
      trafficPattern_[patternId].printTrafficConfiguration(logger_);
      logger_.log("Total Interests Received    = "+toString(trafficPattern_[patternId].totalInterestReceived)+"\n", false, true);
    }
  }

  bool
  checkTrafficPatternCorrectness()
  {
    return true;
  }

  void
  analyzeConfigurationFile()
  {
    int patternId;
    int lineNumber;
    bool skipLine;
    std::string patternLine;
    std::ifstream patternFile;
    logger_.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
    patternFile.open(configurationFile_.c_str());
    if (patternFile.is_open())
    {
      patternId = 0;
      lineNumber = 0;
      while (getline(patternFile, patternLine))
      {
        lineNumber++;
        if (std::isalpha(patternLine[0]))
        {
          DataTrafficConfiguration dataData;
          skipLine = false;
          patternId++;
          if (dataData.processConfigurationDetail(patternLine, logger_, lineNumber))
          {
            while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
            {
              lineNumber++;
              if (!dataData.processConfigurationDetail(patternLine, logger_, lineNumber))
              {
                skipLine = true;
                break;
              }
            }
            lineNumber++;
          }
          else
            skipLine = true;
          if( !skipLine )
          {
            if (dataData.checkTrafficDetailCorrectness())
              trafficPattern_.push_back(dataData);
          }
        }
      }
      patternFile.close();
      if (!checkTrafficPatternCorrectness())
      {
        logger_.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
        logger_.shutdownLogger();
        exit(1);
      }
      logger_.log("Traffic Configuration File Processing Completed\n", true, false);
      for (patternId = 0; patternId < trafficPattern_.size(); patternId++)
      {
        logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
        trafficPattern_[patternId].printTrafficConfiguration(logger_);
        logger_.log("", false, false);
      }
    }
    else
    {
      logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
      logger_.shutdownLogger();
      exit(1);
    }
  }

  void
  initializeTrafficConfiguration()
  {
    if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
    {
      if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
      {
        analyzeConfigurationFile();
      }
      else
      {
        logger_.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
        logger_.shutdownLogger();
        exit(1);
      }
    }
    else
    {
      logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
      logger_.shutdownLogger();
      exit(1);
    }
  }

  static std::string
  getRandomByteString( int randomSize )
  {
    int i;
    std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
    std::string randomData;
    for (i=0; i<randomSize; i++)
      randomData += characterSet[std::rand() % characterSet.length()];
    return randomData;
  }

  void
  onInterest( const Name& name, const Interest& interest, int patternId )
  {
    std::string content, logLine;
    content = "";
    logLine = "";

    Data data(interest.getName());
    if (trafficPattern_[patternId].contentType >= 0)
      data.setContentType(trafficPattern_[patternId].contentType);
    if (trafficPattern_[patternId].freshnessPeriod >= 0)
      data.setFreshnessPeriod(trafficPattern_[patternId].freshnessPeriod);
    if (trafficPattern_[patternId].contentBytes >= 0)
      content = getRandomByteString(trafficPattern_[patternId].contentBytes);
    if (trafficPattern_[patternId].content != "")
      content = trafficPattern_[patternId].content;
    data.setContent((const uint8_t*)content.c_str(), content.length());
    keyChain_.sign(data);
    totalInterestReceived_++;
    trafficPattern_[patternId].totalInterestReceived++;
    logLine += "Interest Received          - PatternType="+toString(patternId+1);
    logLine += ", GlobalID="+toString(totalInterestReceived_);
    logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestReceived);
    logLine += ", Name="+trafficPattern_[patternId].name;
    logger_.log(logLine, true, false);
    usleep(contentDelayTime_*1000);
    face_.put(data);
  }

  void
  onRegisterFailed( const ndn::Name& prefix, const std::string& reason, int patternId )
  {
    std::string logLine;
    logLine = "";
    logLine += "Prefix Registration Failed - PatternType="+toString(patternId+1);
    logLine += ", Name="+trafficPattern_[patternId].name;
    logger_.log(logLine, true, true);
    totalRegistrationsFailed_++;
    if (totalRegistrationsFailed_ == trafficPattern_.size())
      signalHandler();
  }

  void
  initialize()
  {
    boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
    signalSet.async_wait(boost::bind(&NdnTrafficServer::signalHandler, this));
    logger_.initializeLog(instanceId_);
    initializeTrafficConfiguration();

    int patternId;
    for (patternId=0; patternId<trafficPattern_.size(); patternId++ )
    {
      face_.setInterestFilter(  trafficPattern_[patternId].name,
                                func_lib::bind( &NdnTrafficServer::onInterest,
                                                this, _1, _2,
                                                patternId),
                                func_lib::bind( &NdnTrafficServer::onRegisterFailed,
                                                this, _1, _2,
                                                patternId));
    }

    try {
      face_.processEvents();
    }
    catch(std::exception &e) {
      logger_.log("ERROR: "+(std::string)e.what(), true, true);
      logger_.shutdownLogger();
    }
  }

private:

  KeyChain keyChain_;
  std::string programName_;
  std::string instanceId_;
  int contentDelayTime_;
  int totalRegistrationsFailed_;
  Logger logger_;
  std::string configurationFile_;
  ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
  Face face_;
  std::vector<DataTrafficConfiguration> trafficPattern_;
  int totalInterestReceived_;

};

int main( int argc, char* argv[] )
{
  int option;
  NdnTrafficServer ndnTrafficServer (argv[0]);
  while ((option = getopt(argc, argv, "hd:")) != -1) {
    switch (option) {
      case 'h'  :
        ndnTrafficServer.usage();
        break;
      case 'd'  :
        ndnTrafficServer.setContentDelayTime(atoi(optarg));
        break;
      default   :
        ndnTrafficServer.usage();
        break;
    }
  }

  argc -= optind;
  argv += optind;

  if (argv[0] == NULL)
    ndnTrafficServer.usage();

  ndnTrafficServer.setConfigurationFile(argv[0]);
  ndnTrafficServer.initialize();

  return 0;
}
