/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2017,  The University of Memphis,
 *                           Regents of the University of California,
 *                           Arizona Board of Regents.
 *
 * This file is part of NLSR (Named-data Link State Routing).
 * See AUTHORS.md for complete list of NLSR authors and contributors.
 *
 * NLSR 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.
 *
 * NLSR 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
 * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#include "conf-file-processor.hpp"
#include "test-common.hpp"
#include "logger.hpp"
#include "nlsr.hpp"

#include <fstream>
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>

namespace nlsr {
namespace test {

using std::shared_ptr;

const std::string SECTION_GENERAL =
  "general\n"
  "{\n"
  "  network /ndn/\n"
  "  site /memphis.edu/\n"
  "  router /cs/pollux/\n"
  "  lsa-refresh-time 1800\n"
  "  lsa-interest-lifetime 3\n"
  "  router-dead-interval 86400\n"
  "  log-level  INFO\n"
  "  log-dir /tmp\n"
  "  seq-dir /tmp\n"
  "}\n\n";

const std::string LOG4CXX_PLACEHOLDER = "$LOG4CXX$";

const std::string SECTION_GENERAL_WITH_LOG4CXX =
  "general\n"
  "{\n"
  "  network /ndn/\n"
  "  site /memphis.edu/\n"
  "  router /cs/pollux/\n"
  "  lsa-refresh-time 1800\n"
  "  lsa-interest-lifetime 3\n"
  "  router-dead-interval 86400\n"
  "  log-level  INFO\n"
  "  log-dir /tmp\n"
  "  seq-dir /tmp\n"
  "  log4cxx-conf " + LOG4CXX_PLACEHOLDER + "\n"
  "}\n\n";

const std::string SECTION_NEIGHBORS =
  "neighbors\n"
  "{\n"
  "  hello-retries 3\n"
  "  hello-timeout 1\n"
  "  hello-interval  60\n\n"
  "  adj-lsa-build-interval 3\n"
  "  first-hello-interval  6\n"
  "  neighbor\n"
  "  {\n"
  "    name /ndn/memphis.edu/cs/castor\n"
  "    face-uri  udp4://localhost\n"
  "    link-cost 20\n"
  "  }\n\n"
  "  neighbor\n"
  "  {\n"
  "    name /ndn/memphis.edu/cs/mira\n"
  "    face-uri  udp4://localhost\n"
  "    link-cost 30\n"
  "  }\n"
  "}\n\n";

const std::string SECTION_HYPERBOLIC_ON =
  "hyperbolic\n"
  "{\n"
  "  state on\n"
  "  radius   123.456\n"
  "  angle    1.45\n"
  "}\n\n";

const std::string SECTION_HYPERBOLIC_ANGLES_ON =
    "hyperbolic\n"
    "{\n"
    "  state on\n"
    "  radius   123.456\n"
    "  angle    1.45,2.25\n"
    "}\n\n";

const std::string SECTION_HYPERBOLIC_OFF =
  "hyperbolic\n"
  "{\n"
  "  state off\n"
  "  radius   123.456\n"
  "  angle    1.45\n"
  "}\n\n";

const std::string SECTION_FIB =
  "fib\n"
  "{\n"
  "   max-faces-per-prefix 3\n"
  "   routing-calc-interval 9\n"
  "}\n\n";

const std::string SECTION_ADVERTISING =
  "advertising\n"
  "{\n"
  "  prefix /ndn/edu/memphis/cs/netlab\n"
  "  prefix /ndn/edu/memphis/sports/basketball\n"
  "}\n";

const std::string CONFIG_LINK_STATE = SECTION_GENERAL + SECTION_NEIGHBORS +
                                      SECTION_HYPERBOLIC_OFF + SECTION_FIB + SECTION_ADVERTISING;

const std::string CONFIG_LOG4CXX = SECTION_GENERAL_WITH_LOG4CXX;

const std::string CONFIG_HYPERBOLIC = SECTION_GENERAL + SECTION_NEIGHBORS +
                                      SECTION_HYPERBOLIC_ON + SECTION_FIB + SECTION_ADVERTISING;

const std::string CONFIG_HYPERBOLIC_ANGLES = SECTION_GENERAL + SECTION_NEIGHBORS +
                                             SECTION_HYPERBOLIC_ANGLES_ON + SECTION_FIB +
                                             SECTION_ADVERTISING;

class ConfFileProcessorFixture : public BaseFixture
{
public:
  ConfFileProcessorFixture()
    : face(std::make_shared<ndn::util::DummyClientFace>())
    , nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
    , CONFIG_FILE("unit-test-nlsr.conf")
    , m_logConfigFileName(boost::filesystem::unique_path().native())
    , m_logFileName(boost::filesystem::unique_path().native())
  {
  }

  ~ConfFileProcessorFixture()
  {
    remove("unit-test-nlsr.conf");
    remove("/tmp/unit-test-log4cxx.xml");

    boost::filesystem::remove(boost::filesystem::path(getLogConfigFileName()));
    boost::filesystem::remove(boost::filesystem::path(getLogFileName()));
  }

  bool processConfigurationString(std::string confString)
  {
    std::ofstream config;
    config.open("unit-test-nlsr.conf");
    config << confString;
    config.close();

    ConfFileProcessor processor(nlsr, CONFIG_FILE);
    return processor.processConfFile();
  }

  void
  verifyOutputLog4cxx(const std::string expected[], size_t nExpected)
  {
    std::ifstream is(getLogFileName().c_str());
    std::string buffer((std::istreambuf_iterator<char>(is)),
                       (std::istreambuf_iterator<char>()));

    std::vector<std::string> components;
    boost::split(components, buffer, boost::is_any_of(" ,\n"));

    // expected + number of timestamps (one per log statement) + trailing newline of last statement
    BOOST_REQUIRE_EQUAL(components.size(), nExpected);

    for (size_t i = 0; i < nExpected; ++i) {
      if (expected[i] == "")
        continue;

      BOOST_CHECK_EQUAL(components[i], expected[i]);
    }
  }

  const std::string&
  getLogConfigFileName()
  {
    return m_logConfigFileName;
  }

  const std::string&
  getLogFileName()
  {
    return m_logFileName;
  }

  void
  commentOut(const std::string& key, std::string& config)
  {
    boost::replace_all(config, key, ";" + key);
  }

public:
  std::shared_ptr<ndn::util::DummyClientFace> face;
  Nlsr nlsr;

private:
  const std::string CONFIG_FILE;
  std::string m_logConfigFileName;
  std::string m_logFileName;
};

BOOST_FIXTURE_TEST_SUITE(TestConfFileProcessor, ConfFileProcessorFixture)

BOOST_AUTO_TEST_CASE(LinkState)
{
  processConfigurationString(CONFIG_LINK_STATE);
  ConfParameter& conf = nlsr.getConfParameter();
  conf.buildRouterPrefix();

  // General
  BOOST_CHECK_EQUAL(conf.getNetwork(), "/ndn/");
  BOOST_CHECK_EQUAL(conf.getSiteName(), "/memphis.edu/");
  BOOST_CHECK_EQUAL(conf.getRouterName(), "/cs/pollux/");
  BOOST_CHECK_EQUAL(conf.getRouterPrefix(), "/ndn/memphis.edu/cs/pollux/");
  BOOST_CHECK_EQUAL(conf.getChronosyncPrefix(), "/localhop/ndn/NLSR/sync");
  BOOST_CHECK_EQUAL(conf.getLsaPrefix(), "/localhop/ndn/NLSR/LSA");
  BOOST_CHECK_EQUAL(conf.getLsaRefreshTime(), 1800);
  BOOST_CHECK_EQUAL(conf.getLsaInterestLifetime(), ndn::time::seconds(3));
  BOOST_CHECK_EQUAL(conf.getRouterDeadInterval(), 86400);
  BOOST_CHECK_EQUAL(conf.getLogLevel(), "INFO");
  BOOST_CHECK_EQUAL(conf.getLogDir(), "/tmp");
  BOOST_CHECK_EQUAL(conf.getSeqFileDir(), "/tmp");

  // Neighbors
  BOOST_CHECK_EQUAL(conf.getInterestRetryNumber(), 3);
  BOOST_CHECK_EQUAL(conf.getInterestResendTime(), 1);
  BOOST_CHECK_EQUAL(conf.getInfoInterestInterval(), 60);

  BOOST_CHECK_EQUAL(conf.getAdjLsaBuildInterval(), 3);
  BOOST_CHECK_EQUAL(conf.getFirstHelloInterval(), 6);

  BOOST_CHECK(nlsr.getAdjacencyList().isNeighbor("/ndn/memphis.edu/cs/mira"));
  BOOST_CHECK(nlsr.getAdjacencyList().isNeighbor("/ndn/memphis.edu/cs/castor"));
  BOOST_CHECK(!nlsr.getAdjacencyList().isNeighbor("/ndn/memphis.edu/cs/fail"));

  Adjacent mira = nlsr.getAdjacencyList().getAdjacent("/ndn/memphis.edu/cs/mira");
  BOOST_CHECK_EQUAL(mira.getName(), "/ndn/memphis.edu/cs/mira");
  BOOST_CHECK_EQUAL(mira.getLinkCost(), 30);

  Adjacent castor = nlsr.getAdjacencyList().getAdjacent("/ndn/memphis.edu/cs/castor");
  BOOST_CHECK_EQUAL(castor.getName(), "/ndn/memphis.edu/cs/castor");
  BOOST_CHECK_EQUAL(castor.getLinkCost(), 20);

  // Hyperbolic
  BOOST_CHECK_EQUAL(conf.getHyperbolicState(), 0);

  // FIB
  BOOST_CHECK_EQUAL(conf.getMaxFacesPerPrefix(), 3);
  BOOST_CHECK_EQUAL(conf.getRoutingCalcInterval(), 9);

  // Advertising
  BOOST_CHECK_EQUAL(nlsr.getNamePrefixList().size(), 2);
}

BOOST_AUTO_TEST_CASE(Log4cxxFileExists)
{
  std::string configPath = boost::filesystem::unique_path().native();

  std::ofstream log4cxxConfFile;
  log4cxxConfFile.open(configPath);
  log4cxxConfFile.close();

  std::string config = CONFIG_LOG4CXX;
  boost::replace_all(config, LOG4CXX_PLACEHOLDER, configPath);

  BOOST_CHECK_EQUAL(processConfigurationString(config), true);

  ConfParameter& conf = nlsr.getConfParameter();
  BOOST_CHECK_EQUAL(conf.getLog4CxxConfPath(), configPath);
  BOOST_CHECK_EQUAL(conf.isLog4CxxConfAvailable(), true);

  boost::filesystem::remove(boost::filesystem::path(configPath));
}

BOOST_AUTO_TEST_CASE(Log4cxxFileDoesNotExist)
{
  std::string configPath = boost::filesystem::unique_path().native();

  std::string config = CONFIG_LOG4CXX;
  boost::replace_all(config, LOG4CXX_PLACEHOLDER, configPath);

  BOOST_CHECK_EQUAL(processConfigurationString(config), false);
}

BOOST_AUTO_TEST_CASE(Log4cxxNoValue)
{
  std::string config = CONFIG_LOG4CXX;
  boost::replace_all(config, LOG4CXX_PLACEHOLDER, "");

  BOOST_CHECK_EQUAL(processConfigurationString(config), false);
}

BOOST_AUTO_TEST_CASE(Log4cxxTestCase)
{
  {
    std::ofstream of(getLogConfigFileName().c_str());
    of << "log4j.rootLogger=TRACE, FILE\n"
       << "log4j.appender.FILE=org.apache.log4j.FileAppender\n"
       << "log4j.appender.FILE.layout=org.apache.log4j.PatternLayout\n"
       << "log4j.appender.FILE.File=" << getLogFileName() << "\n"
       << "log4j.appender.FILE.ImmediateFlush=true\n"
       << "log4j.appender.FILE.layout.ConversionPattern=%d{HH:mm:ss} %p %c{1} - %m%n\n";
  }

  INIT_LOG4CXX(getLogConfigFileName());

  INIT_LOGGER("DefaultConfig");

  NLSR_LOG_TRACE("trace-message-JHGFDSR^1");
  NLSR_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17);
  NLSR_LOG_INFO("info-message-Jjxjshj13");
  NLSR_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x");
  NLSR_LOG_ERROR("error-message-!#$&^%$#@");
  NLSR_LOG_FATAL("fatal-message-JJSjaamcng");

  const std::string EXPECTED[] =
    {
      "", "TRACE", "DefaultConfig", "-", "trace-message-JHGFDSR^1",
      "", "DEBUG", "DefaultConfig", "-", "debug-message-IGg2474fdksd-fo-151617",
      "", "INFO",  "DefaultConfig", "-", "info-message-Jjxjshj13",
      "", "WARN",  "DefaultConfig", "-", "warning-message-XXXhdhd111x",
      "", "ERROR", "DefaultConfig", "-", "error-message-!#$&^%$#@",
      "", "FATAL", "DefaultConfig", "-", "fatal-message-JJSjaamcng",
      "",
    };

  verifyOutputLog4cxx(EXPECTED, sizeof(EXPECTED) / sizeof(std::string));
}

BOOST_AUTO_TEST_CASE(MalformedUri)
{
  const std::string MALFORMED_URI =
    "neighbors\n"
    "{\n"
    "  hello-retries 3\n"
    "  hello-timeout 1\n"
    "  hello-interval  60\n\n"
    "  adj-lsa-build-interval 3\n"
    "  first-hello-interval  6\n"
    "  neighbor\n"
    "  {\n"
    "    name /ndn/memphis.edu/cs/castor\n"
    "    face-uri  udp4:malformed-uri\n"
    "    link-cost 20\n"
    "  }\n"
    "}\n\n";

  BOOST_CHECK_EQUAL(processConfigurationString(MALFORMED_URI), false);
}

BOOST_AUTO_TEST_CASE(Hyperbolic)
{
  processConfigurationString(CONFIG_HYPERBOLIC);

  ConfParameter& conf = nlsr.getConfParameter();
  BOOST_CHECK_EQUAL(conf.getHyperbolicState(), 1);
  BOOST_CHECK_EQUAL(conf.getCorR(), 123.456);
  std::vector<double> angles;
  angles.push_back(1.45);
  BOOST_CHECK(conf.getCorTheta() == angles);
}

BOOST_AUTO_TEST_CASE(Hyperbolic2)
{
  processConfigurationString(CONFIG_HYPERBOLIC_ANGLES);

  ConfParameter& conf = nlsr.getConfParameter();
  BOOST_CHECK_EQUAL(conf.getHyperbolicState(), 1);
  BOOST_CHECK_EQUAL(conf.getCorR(), 123.456);
  std::vector<double> angles;
  angles.push_back(1.45);
  angles.push_back(2.25);
  BOOST_CHECK(conf.getCorTheta() == angles);
}

BOOST_AUTO_TEST_CASE(DefaultValuesGeneral)
{
  std::string config = SECTION_GENERAL;

  commentOut("lsa-refresh-time", config);
  commentOut("lsa-interest-lifetime", config);
  commentOut("router-dead-interval", config);
  commentOut("log-level", config);

  BOOST_CHECK_EQUAL(processConfigurationString(config), true);

  ConfParameter& conf = nlsr.getConfParameter();

  BOOST_CHECK_EQUAL(conf.getLsaRefreshTime(), static_cast<uint32_t>(LSA_REFRESH_TIME_DEFAULT));
  BOOST_CHECK_EQUAL(conf.getLsaInterestLifetime(),
                    static_cast<ndn::time::seconds>(LSA_INTEREST_LIFETIME_DEFAULT));
  BOOST_CHECK_EQUAL(conf.getRouterDeadInterval(), (2*conf.getLsaRefreshTime()));
  BOOST_CHECK_EQUAL(conf.getLogLevel(), "INFO");
}

BOOST_AUTO_TEST_CASE(DefaultValuesNeighbors)
{
  std::string config = SECTION_NEIGHBORS;

  commentOut("hello-retries", config);
  commentOut("hello-timeout", config);
  commentOut("hello-interval", config);
  commentOut("first-hello-interval", config);
  commentOut("adj-lsa-build-interval", config);

  BOOST_CHECK_EQUAL(processConfigurationString(config), true);

  ConfParameter& conf = nlsr.getConfParameter();

  BOOST_CHECK_EQUAL(conf.getInterestRetryNumber(), static_cast<uint32_t>(HELLO_RETRIES_DEFAULT));
  BOOST_CHECK_EQUAL(conf.getInterestResendTime(), static_cast<uint32_t>(HELLO_TIMEOUT_DEFAULT));
  BOOST_CHECK_EQUAL(conf.getInfoInterestInterval(), static_cast<uint32_t>(HELLO_INTERVAL_DEFAULT));
  BOOST_CHECK_EQUAL(conf.getFirstHelloInterval(),
                    static_cast<uint32_t>(FIRST_HELLO_INTERVAL_DEFAULT));
  BOOST_CHECK_EQUAL(conf.getAdjLsaBuildInterval(),
                    static_cast<uint32_t>(ADJ_LSA_BUILD_INTERVAL_DEFAULT));
}

BOOST_AUTO_TEST_CASE(DefaultValuesFib)
{
  std::string config = SECTION_FIB;

  commentOut("max-faces-per-prefix", config);
  commentOut("routing-calc-interval", config);

  BOOST_CHECK_EQUAL(processConfigurationString(config), true);

  ConfParameter& conf = nlsr.getConfParameter();

  BOOST_CHECK_EQUAL(conf.getMaxFacesPerPrefix(),
                    static_cast<uint32_t>(MAX_FACES_PER_PREFIX_DEFAULT));
  BOOST_CHECK_EQUAL(conf.getRoutingCalcInterval(),
                    static_cast<uint32_t>(ROUTING_CALC_INTERVAL_DEFAULT));
}

BOOST_AUTO_TEST_CASE(DefaultValuesHyperbolic)
{
  std::string config = SECTION_HYPERBOLIC_ON;

  commentOut("state", config);

  BOOST_CHECK_EQUAL(processConfigurationString(config), true);

  ConfParameter& conf = nlsr.getConfParameter();

  BOOST_CHECK_EQUAL(conf.getHyperbolicState(), static_cast<int32_t>(HYPERBOLIC_STATE_DEFAULT));
}

BOOST_AUTO_TEST_CASE(OutOfRangeValue)
{
  const std::string SECTION_FIB_OUT_OF_RANGE =
  "fib\n"
  "{\n"
  "   max-faces-per-prefix 3\n"
  "   routing-calc-interval 999\n" // Larger than max value
  "}\n\n";

  // Processing should fail due to out of range value
  BOOST_CHECK_EQUAL(processConfigurationString(SECTION_FIB_OUT_OF_RANGE), false);
}

BOOST_AUTO_TEST_CASE(NegativeValue)
{
  const std::string SECTION_GENERAL_NEGATIVE_VALUE =
  "general\n"
  "{\n"
  "  network /ndn/\n"
  "  site /memphis.edu/\n"
  "  router /cs/pollux/\n"
  "  lsa-refresh-time -1800\n"
  "  lsa-interest-lifetime -3\n"
  "  router-dead-interval -86400\n"
  "}\n\n";

  // Processing should fail due to negative value
  BOOST_CHECK_EQUAL(processConfigurationString(SECTION_GENERAL_NEGATIVE_VALUE), false);
}

BOOST_AUTO_TEST_CASE(LoadCertToPublish)
{
  ndn::Name identity("/TestNLSR/identity");
  identity.appendVersion();

  ndn::KeyChain keyChain;
  keyChain.createIdentity(identity);
  ndn::Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
  std::shared_ptr<ndn::IdentityCertificate> certificate = keyChain.getCertificate(certName);

  const boost::filesystem::path CERT_PATH =
      (boost::filesystem::current_path() / std::string("cert-to-publish.cert"));
  ndn::io::save(*certificate, CERT_PATH.string());

  const std::string SECTION_SECURITY =
  "security\n"
  "{\n"
  "  validator\n"
  "  {\n"
  "    trust-anchor\n"
  "    {\n"
  "      type any\n"
  "    }\n"
  "  }\n"
  "  prefix-update-validator\n"
  "  {\n"
  "    trust-anchor\n"
  "    {\n"
  "      type any\n"
  "    }\n"
  "  }\n"
  "  cert-to-publish \"cert-to-publish.cert\"\n"
  "}\n\n";

  BOOST_CHECK(processConfigurationString(SECTION_SECURITY));

  // Certificate should now be in the CertificateStore
  const security::CertificateStore& certStore = nlsr.getCertificateStore();
  const ndn::Name certKey = certificate->getName().getPrefix(-1);

  BOOST_CHECK(certStore.find(certKey) != nullptr);

  // Cleanup
  keyChain.deleteIdentity(identity);
  boost::filesystem::remove(CERT_PATH);
}

BOOST_AUTO_TEST_CASE(PrefixUpdateValidatorOptional) // Bug #2814
{
  const std::string SECTION_SECURITY =
  "security\n"
  "{\n"
  "  validator\n"
  "  {\n"
  "    trust-anchor\n"
  "    {\n"
  "      type any\n"
  "    }\n"
  "  }\n"
  "}\n\n";

  BOOST_CHECK(processConfigurationString(SECTION_SECURITY));
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace test
} // namespace nlsr
