/* -*- 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 <boost/lexical_cast.hpp>

#include <ndn-cpp-dev/face.hpp>
#include <ndn-cpp-dev/security/key-chain.hpp>

#include "logger.hpp"

namespace ndn {

class NdnTrafficServer
{
public:

  explicit
  NdnTrafficServer(char* programName)
    : m_logger("NdnTrafficServer")
    , m_programName(programName)
    , m_hasError(false)
    , m_nRegistrationsFailed(0)
    , m_nMaximumInterests(-1)
    , m_nInterestsReceived(0)
    , m_contentDelay(time::milliseconds(-1))
    , m_ioService(new boost::asio::io_service)
    , m_face(m_ioService)
  {
    m_instanceId = boost::lexical_cast<std::string>(std::rand());
  }

  class DataTrafficConfiguration
  {
  public:
    DataTrafficConfiguration()
      : m_contentType(-1)
      , m_freshnessPeriod(time::milliseconds(-1))
      , m_contentBytes(-1)
      , m_contentDelay(time::milliseconds(-1))
      , m_nInterestsReceived(0)
    {
    }

    void
    printTrafficConfiguration(Logger& logger)
    {
      std::string detail = "";
      if (m_name != "")
        detail += "Name=" + m_name + ", ";
      if (m_contentType >= 0)
        detail += "ContentType=" + boost::lexical_cast<std::string>(m_contentType) + ", ";
      if (m_freshnessPeriod >= time::milliseconds(0))
        detail += "FreshnessPeriod=" +
          boost::lexical_cast<std::string>(static_cast<int>(m_freshnessPeriod.count())) + ", ";
      if (m_contentBytes >= 0)
        detail += "ContentBytes=" + boost::lexical_cast<std::string>(m_contentBytes) + ", ";
      if (m_contentDelay >= time::milliseconds(0))
        detail += "ContentDelay=" +
          boost::lexical_cast<std::string>(m_contentDelay.count()) + ", ";
      if (m_content != "")
        detail += "Content=" + m_content + ", ";
      if (detail.length() >= 2)
        detail = detail.substr(0, detail.length() - 2);
      logger.log(detail, false, false);
    }


    bool
    extractParameterValue(const std::string& detail,
                          std::string& parameter,
                          std::string& value)
    {
      std::string allowedCharacters = ":/+._-%";
      parameter = "";
      value = "";
      int 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(const std::string& detail,
                               Logger& logger,
                               int lineNumber)
    {
      std::string parameter, value;
      if (extractParameterValue(detail, parameter, value))
        {
          if (parameter == "Name")
            m_name = value;
          else if (parameter == "ContentType")
            m_contentType = boost::lexical_cast<int>(value);
          else if (parameter == "FreshnessPeriod")
            m_freshnessPeriod = time::milliseconds(boost::lexical_cast<int>(value));
          else if (parameter == "ContentDelay")
            m_contentDelay = time::milliseconds(boost::lexical_cast<int>(value));
          else if (parameter == "ContentBytes")
            m_contentBytes = boost::lexical_cast<int>(value);
          else if (parameter == "Content")
            m_content = value;
          else
            logger.log("Line " + boost::lexical_cast<std::string>(lineNumber) +
                       " \t- Invalid Parameter='" + parameter + "'", false, true);
        }
      else
        {
          logger.log("Line " + boost::lexical_cast<std::string>(lineNumber) +
            " \t- Improper Traffic Configuration Line - " + detail, false, true);
          return false;
        }
      return true;
    }

    bool
    checkTrafficDetailCorrectness()
    {
      return true;
    }

    std::string m_name;
    int m_contentType;
    time::milliseconds m_freshnessPeriod;
    int m_contentBytes;
    time::milliseconds m_contentDelay;
    std::string m_content;
    int m_nInterestsReceived;

  };

  void
  usage()
  {

    std::cout << "\nUsage: " << m_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\n"
      "  [-c count]    - specify maximum number of interests to be satisfied\n"
      "  [-h]          - print help and exit\n\n";
    exit(1);

  }

  void
  setMaximumInterests(int maximumInterests)
  {
    if (maximumInterests < 0)
      usage();
    m_nMaximumInterests = maximumInterests;
  }

  bool
  hasError() const
  {
    return m_hasError;
  }

  void
  setContentDelay(int contentDelay)
  {
    if (contentDelay < 0)
      usage();
    m_contentDelay = time::milliseconds(contentDelay);
  }

  void
  setConfigurationFile(char* configurationFile)
  {
    m_configurationFile = configurationFile;
  }

  void
  signalHandler()
  {
    logStatistics();
    m_logger.shutdownLogger();
    m_face.shutdown();
    m_ioService->stop();
    if (m_hasError)
      exit(1);
    else
      exit(0);
  }

  void
  logStatistics()
  {
    m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
    m_logger.log("Total Traffic Pattern Types = " +
      boost::lexical_cast<std::string>(m_trafficPatterns.size()), false, true);
    m_logger.log("Total Interests Received    = " +
      boost::lexical_cast<std::string>(m_nInterestsReceived), false, true);
    if (m_nInterestsReceived < m_nMaximumInterests)
      m_hasError = true;
    for (int patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
      {
        m_logger.log("\nTraffic Pattern Type #" +
          boost::lexical_cast<std::string>(patternId + 1), false, true);
        m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
        m_logger.log("Total Interests Received    = " +
          boost::lexical_cast<std::string>(
            m_trafficPatterns[patternId].m_nInterestsReceived) + "\n", false, true);
      }
  }

  bool
  checkTrafficPatternCorrectness()
  {
    return true;
  }

  void
  parseConfigurationFile()
  {
    std::string patternLine;
    std::ifstream patternFile;
    m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
    patternFile.open(m_configurationFile.c_str());
    if (patternFile.is_open())
      {
        int patternId = 0;
        int lineNumber = 0;
        while (getline(patternFile, patternLine))
          {
            lineNumber++;
            if (std::isalpha(patternLine[0]))
              {
                DataTrafficConfiguration dataData;
                bool shouldSkipLine = 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))
                          {
                            shouldSkipLine = true;
                            break;
                          }
                      }
                    lineNumber++;
                  }
                else
                  shouldSkipLine = true;
                if (!shouldSkipLine)
                  {
                    if (dataData.checkTrafficDetailCorrectness())
                      m_trafficPatterns.push_back(dataData);
                  }
              }
          }
        patternFile.close();
        if (!checkTrafficPatternCorrectness())
          {
            m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " +
                         m_configurationFile, false, true);
            m_logger.shutdownLogger();
            exit(1);
          }
        m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
        for (patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
          {
            m_logger.log("Traffic Pattern Type #" +
              boost::lexical_cast<std::string>(patternId + 1), false, false);
            m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
            m_logger.log("", false, false);
          }
      }
    else
      {
        m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
          m_configurationFile, false, true);
        m_logger.shutdownLogger();
        exit(1);
      }
  }

  void
  initializeTrafficConfiguration()
  {
    if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
      {
        if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
          {
            parseConfigurationFile();
          }
        else
          {
            m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
              m_configurationFile, false, true);
            m_logger.shutdownLogger();
            exit(1);
          }
      }
    else
      {
        m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
          m_configurationFile, false, true);
        m_logger.shutdownLogger();
        exit(1);
      }
  }

  static std::string
  getRandomByteString(int randomSize)
  {
    std::string randomString;
    for (int i = 0; i < randomSize; i++)
      randomString += static_cast<char>(std::rand() % 128);
    return randomString;
  }

  void
  onInterest(const Name& name, const Interest& interest, int patternId)
  {
    if (m_nMaximumInterests < 0 || m_nInterestsReceived < m_nMaximumInterests)
      {
        Data data(interest.getName());

        if (m_trafficPatterns[patternId].m_contentType >= 0)
          data.setContentType(m_trafficPatterns[patternId].m_contentType);

        if (m_trafficPatterns[patternId].m_freshnessPeriod >= time::milliseconds(0))
          data.setFreshnessPeriod(m_trafficPatterns[patternId].m_freshnessPeriod);

        std::string content = "";
        if (m_trafficPatterns[patternId].m_contentBytes >= 0)
          content = getRandomByteString(m_trafficPatterns[patternId].m_contentBytes);
        if (m_trafficPatterns[patternId].m_content != "")
          content = m_trafficPatterns[patternId].m_content;

        data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.length());
        m_keyChain.sign(data);
        m_nInterestsReceived++;
        m_trafficPatterns[patternId].m_nInterestsReceived++;
        std::string logLine = "Interest Received          - PatternType=" +
          boost::lexical_cast<std::string>(patternId + 1);
        logLine += ", GlobalID=" + boost::lexical_cast<std::string>(m_nInterestsReceived);
        logLine += ", LocalID=" +
          boost::lexical_cast<std::string>(m_trafficPatterns[patternId].m_nInterestsReceived);
        logLine += ", Name=" + m_trafficPatterns[patternId].m_name;
        m_logger.log(logLine, true, false);
        if (m_trafficPatterns[patternId].m_contentDelay > time::milliseconds(-1))
          usleep(m_trafficPatterns[patternId].m_contentDelay.count() * 1000);
        if (m_contentDelay > time::milliseconds(-1))
          usleep(m_contentDelay.count() * 1000);
        m_face.put(data);
      }
    if (m_nMaximumInterests >= 0 && m_nInterestsReceived == m_nMaximumInterests)
      {
        logStatistics();
        m_logger.shutdownLogger();
        m_face.shutdown();
        m_ioService->stop();
      }
  }

  void
  onRegisterFailed(const ndn::Name& prefix, const std::string& reason, int patternId)
  {
    std::string logLine = "";
    logLine += "Prefix Registration Failed - PatternType=" +
      boost::lexical_cast<std::string>(patternId + 1);
    logLine += ", Name=" + m_trafficPatterns[patternId].m_name;
    m_logger.log(logLine, true, true);
    m_nRegistrationsFailed++;
    if (m_nRegistrationsFailed == m_trafficPatterns.size())
      {
        m_hasError = true;
        signalHandler();
      }
  }

  void
  run()
  {
    boost::asio::signal_set signalSet(*m_ioService, SIGINT, SIGTERM);
    signalSet.async_wait(boost::bind(&NdnTrafficServer::signalHandler, this));
    m_logger.initializeLog(m_instanceId);
    initializeTrafficConfiguration();
    if (m_nMaximumInterests == 0)
      {
        logStatistics();
        m_logger.shutdownLogger();
        return;
      }

    for (int patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
      {
        m_face.setInterestFilter(m_trafficPatterns[patternId].m_name,
                                 bind(&NdnTrafficServer::onInterest,
                                      this, _1, _2,
                                      patternId),
                                 bind(&NdnTrafficServer::onRegisterFailed,
                                      this, _1, _2,
                                      patternId));
      }

    try {
      m_face.processEvents();
    }
    catch (std::exception& e) {
      m_logger.log("ERROR: " + static_cast<std::string>(e.what()), true, true);
      m_logger.shutdownLogger();
      m_hasError = true;
      m_ioService->stop();
    }
  }

private:
  KeyChain m_keyChain;
  std::string m_programName;
  bool m_hasError;
  std::string m_instanceId;
  time::milliseconds m_contentDelay;
  int m_nRegistrationsFailed;
  Logger m_logger;
  std::string m_configurationFile;
  shared_ptr<boost::asio::io_service> m_ioService;
  Face m_face;
  std::vector<DataTrafficConfiguration> m_trafficPatterns;
  int m_nMaximumInterests;
  int m_nInterestsReceived;
};

} // namespace ndn

int
main(int argc, char* argv[])
{
  std::srand(std::time(0));
  ndn::NdnTrafficServer ndnTrafficServer(argv[0]);
  int option;
  while ((option = getopt(argc, argv, "hc:d:")) != -1) {
    switch (option) {
    case 'h':
      ndnTrafficServer.usage();
      break;
    case 'c':
      ndnTrafficServer.setMaximumInterests(atoi(optarg));
      break;
    case 'd':
      ndnTrafficServer.setContentDelay(atoi(optarg));
      break;
    default:
      ndnTrafficServer.usage();
      break;
    }
  }

  argc -= optind;
  argv += optind;

  if (argv[0] == 0)
    ndnTrafficServer.usage();

  ndnTrafficServer.setConfigurationFile(argv[0]);
  ndnTrafficServer.run();

  if (ndnTrafficServer.hasError())
    return 1;
  else
    return 0;
}
