/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2014 University of Arizona.
 *
 * GNU 3.0 License, see the LICENSE file for more information
 *
 * 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>

#include "logger.hpp"

namespace ndn {

class NdnTrafficServer
{
public:
  
  NdnTrafficServer( char* programName )
    : m_logger("NDNTrafficServer")
    , 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() >= 2)
        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()
  {
    m_logger.shutdownLogger();
    face_.shutdown();
    ioService_.reset();
    logStatistics();
    exit(1);
  }

  void
  logStatistics()
  {
    int patternId;
    m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
    m_logger.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);
    m_logger.log("Total Interests Received    = "+toString(totalInterestReceived_), false, true);
    for (patternId=0; patternId<trafficPattern_.size(); patternId++)
      {
        m_logger.log("\nTraffic Pattern Type #"+toString(patternId+1), false, true);
        trafficPattern_[patternId].printTrafficConfiguration(m_logger);
        m_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;
    m_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, m_logger, lineNumber))
                  {
                    while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
                      {
                        lineNumber++;
                        if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
                          {
                            skipLine = true;
                            break;
                          }
                      }
                    lineNumber++;
                  }
                else
                  skipLine = true;
                if( !skipLine )
                  {
                    if (dataData.checkTrafficDetailCorrectness())
                      trafficPattern_.push_back(dataData);
                  }
              }
          }
        patternFile.close();
        if (!checkTrafficPatternCorrectness())
          {
            m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
            m_logger.shutdownLogger();
            exit(1);
          }
        m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
        for (patternId = 0; patternId < trafficPattern_.size(); patternId++)
          {
            m_logger.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
            trafficPattern_[patternId].printTrafficConfiguration(m_logger);
            m_logger.log("", false, false);
          }
      }
    else
      {
        m_logger.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
        m_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
          {
            m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
            m_logger.shutdownLogger();
            exit(1);
          }
      }
    else
      {
        m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
        m_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;
    m_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;
    m_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));
    m_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) {
      m_logger.log("ERROR: "+(std::string)e.what(), true, true);
      m_logger.shutdownLogger();
    }
  }

private:

  KeyChain keyChain_;
  std::string programName_;
  std::string instanceId_;
  int contentDelayTime_;
  int totalRegistrationsFailed_;
  Logger m_logger;
  std::string configurationFile_;
  ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
  Face face_;
  std::vector<DataTrafficConfiguration> trafficPattern_;
  int totalInterestReceived_;

};

} // namespace ndn

int main( int argc, char* argv[] )
{
  int option;
  ndn::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;
}
