/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2014-2015  University of Arizona.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
 */

#include <cctype>
#include <cstdlib>
#include <fstream>
#include <string>
#include <unistd.h>
#include <vector>

#include <boost/asio/io_service.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/filesystem.hpp>
#include <boost/noncopyable.hpp>

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>

#include "logger.hpp"

namespace ndn {

class NdnTrafficServer : boost::noncopyable
{
public:
  explicit
  NdnTrafficServer(const char* programName)
    : m_logger("NdnTrafficServer")
    , m_programName(programName)
    , m_hasError(false)
    , m_hasQuietLogging(false)
    , m_nRegistrationsFailed(0)
    , m_nMaximumInterests(-1)
    , m_nInterestsReceived(0)
    , m_contentDelay(time::milliseconds(-1))
    , m_instanceId(std::to_string(std::rand()))
    , m_face(m_ioService)
  {
  }

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

    void
    printTrafficConfiguration(Logger& logger)
    {
      std::string detail;

      if (!m_name.empty())
        detail += "Name=" + m_name + ", ";
      if (m_contentType >= 0)
        detail += "ContentType=" + std::to_string(m_contentType) + ", ";
      if (m_freshnessPeriod >= time::milliseconds(0))
        detail += "FreshnessPeriod=" +
                  std::to_string(static_cast<int>(m_freshnessPeriod.count())) + ", ";
      if (m_contentBytes >= 0)
        detail += "ContentBytes=" + std::to_string(m_contentBytes) + ", ";
      if (m_contentDelay >= time::milliseconds(0))
        detail += "ContentDelay=" + std::to_string(m_contentDelay.count()) + ", ";
      if (!m_content.empty())
        detail += "Content=" + m_content + ", ";
      detail += "SignWithSha256=" + std::to_string(m_signWithSha256) + ", ";
      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 = ":/+._-%";
      std::size_t i = 0;

      parameter = "";
      value = "";
      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.empty() || value.empty())
        return false;
      else
        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 = std::stoi(value);
        }
        else if (parameter == "FreshnessPeriod") {
          m_freshnessPeriod = time::milliseconds(std::stoi(value));
        }
        else if (parameter == "ContentDelay") {
          m_contentDelay = time::milliseconds(std::stoi(value));
        }
        else if (parameter == "ContentBytes") {
          m_contentBytes = std::stoi(value);
        }
        else if (parameter == "Content") {
          m_content = value;
        }
        else if (parameter == "SignWithSha256") {
          if (value == "0") {
            m_signWithSha256 = false;
          }
          else if (value == "1") {
            m_signWithSha256 = true;
          }
          else {
            logger.log("Line " + std::to_string(lineNumber) +
                       " \t- Invalid SignWithSha256 Value='" + value + "'", false, true);
          }
        }
        else {
          logger.log("Line " + std::to_string(lineNumber) +
                     " \t- Invalid Parameter='" + parameter + "'", false, true);
        }
      }
      else {
        logger.log("Line " + std::to_string(lineNumber) +
                   " \t- Improper Traffic Configuration Line - " + detail, false, true);
        return false;
      }

      return true;
    }

    bool
    checkTrafficDetailCorrectness()
    {
      return true;
    }

  private:
    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;
    bool m_signWithSha256;

    friend class NdnTrafficServer;
  };

  void
  usage() const
  {
    std::cout << "Usage:\n"
              << "  " << m_programName << " [options] <Traffic_Configuration_File>\n"
              << "\n"
              << "Respond to Interests as per provided Traffic Configuration File.\n"
              << "Multiple prefixes can be configured for handling.\n"
              << "Set environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
              << "\n"
              << "Options:\n"
              << "  [-d interval] - set delay before responding to interest, in milliseconds\n"
              << "  [-c count]    - specify maximum number of interests to be satisfied\n"
              << "  [-q]          - quiet mode: no interest reception/data generation logging\n"
              << "  [-h]          - print this help text and exit\n";
    exit(EXIT_FAILURE);
  }

  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(const char* configurationFile)
  {
    m_configurationFile = configurationFile;
  }

  void
  setQuietLogging()
  {
    m_hasQuietLogging = true;
  }

  void
  signalHandler()
  {
    logStatistics();

    m_logger.shutdownLogger();
    m_face.shutdown();
    m_ioService.stop();

    exit(m_hasError ? EXIT_FAILURE : EXIT_SUCCESS);
  }

  void
  logStatistics()
  {
    m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
    m_logger.log("Total Traffic Pattern Types = " +
                 std::to_string(m_trafficPatterns.size()), false, true);
    m_logger.log("Total Interests Received    = " +
                 std::to_string(m_nInterestsReceived), false, true);

    if (m_nInterestsReceived < m_nMaximumInterests)
      m_hasError = true;

    for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
      {
        m_logger.log("\nTraffic Pattern Type #" + std::to_string(patternId + 1), false, true);
        m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
        m_logger.log("Total Interests Received    = " + std::to_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 lineNumber = 0;
        while (getline(patternFile, patternLine))
          {
            lineNumber++;
            if (std::isalpha(patternLine[0]))
              {
                DataTrafficConfiguration dataData;
                bool shouldSkipLine = false;
                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(EXIT_FAILURE);
          }

        m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
        for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
          {
            m_logger.log("Traffic Pattern Type #" +
                         std::to_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(EXIT_FAILURE);
      }
  }

  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(EXIT_FAILURE);
          }
      }
    else
      {
        m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
          m_configurationFile, false, true);
        m_logger.shutdownLogger();
        exit(EXIT_FAILURE);
      }
  }

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

  void
  onInterest(const Name& name, const Interest& interest, int patternId)
  {
    auto& pattern = m_trafficPatterns[patternId];

    if (m_nMaximumInterests < 0 || m_nInterestsReceived < m_nMaximumInterests)
      {
        Data data(interest.getName());

        if (pattern.m_contentType >= 0)
          data.setContentType(pattern.m_contentType);

        if (pattern.m_freshnessPeriod >= time::milliseconds(0))
          data.setFreshnessPeriod(pattern.m_freshnessPeriod);

        std::string content;
        if (pattern.m_contentBytes >= 0)
          content = getRandomByteString(pattern.m_contentBytes);
        if (!pattern.m_content.empty())
          content = pattern.m_content;

        data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.length());

        if (pattern.m_signWithSha256) {
          m_keyChain.sign(data, security::signingWithSha256());
        }
        else {
          m_keyChain.sign(data);
        }

        m_nInterestsReceived++;
        pattern.m_nInterestsReceived++;

        if (!m_hasQuietLogging) {
          std::string logLine =
            "Interest Received          - PatternType=" + std::to_string(patternId + 1) +
            ", GlobalID=" + std::to_string(m_nInterestsReceived) +
            ", LocalID=" + std::to_string(pattern.m_nInterestsReceived) +
            ", Name=" + pattern.m_name;
          m_logger.log(logLine, true, false);
        }

        if (pattern.m_contentDelay > time::milliseconds(-1))
          usleep(pattern.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=" + std::to_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(bind(&NdnTrafficServer::signalHandler, this));

    m_logger.initializeLog(m_instanceId);
    initializeTrafficConfiguration();
    if (m_nMaximumInterests == 0)
      {
        logStatistics();
        m_logger.shutdownLogger();
        return;
      }

    for (std::size_t 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 (const std::exception& e) {
      m_logger.log("ERROR: " + std::string(e.what()), true, true);
      m_logger.shutdownLogger();
      m_hasError = true;
      m_ioService.stop();
    }
  }

private:
  KeyChain m_keyChain;
  Logger m_logger;
  std::string m_programName;
  bool m_hasError;
  bool m_hasQuietLogging;
  std::size_t m_nRegistrationsFailed;
  int m_nMaximumInterests;
  int m_nInterestsReceived;
  time::milliseconds m_contentDelay;
  std::string m_instanceId;
  std::string m_configurationFile;

  boost::asio::io_service m_ioService;
  Face m_face;
  std::vector<DataTrafficConfiguration> m_trafficPatterns;
};

} // namespace ndn

int
main(int argc, char* argv[])
{
  std::srand(std::time(nullptr));

  ndn::NdnTrafficServer server(argv[0]);
  int option;
  while ((option = getopt(argc, argv, "hqc:d:")) != -1) {
    switch (option) {
    case 'h':
      server.usage();
      break;
    case 'c':
      server.setMaximumInterests(atoi(optarg));
      break;
    case 'd':
      server.setContentDelay(atoi(optarg));
      break;
    case 'q':
      server.setQuietLogging();
      break;
    default:
      server.usage();
      break;
    }
  }

  argc -= optind;
  argv += optind;

  if (!argc)
    server.usage();

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

  return server.hasError() ? EXIT_FAILURE : EXIT_SUCCESS;
}