/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (C) 2014 Named Data Networking Project
 * See COPYING for copyright and distribution information.
 */


#include "mgmt/config-file.hpp"

#include <boost/test/unit_test.hpp>

namespace nfd {

NFD_LOG_INIT("ConfigFileTest");

BOOST_AUTO_TEST_SUITE(MgmtConfigFile)

// a
// {
//    akey "avalue"
// }
// b
// {
//   bkey "bvalue"
// }

const std::string CONFIG =
"a\n"
"{\n"
"        akey \"avalue\"\n"
"}\n"
"b\n"
"{\n"
"        bkey \"bvalue\"\n"
"}\n";


// a
// {
//    akey "avalue"
// }
// b
//
//   bkey "bvalue"
// }

const std::string MALFORMED_CONFIG =
"a\n"
"{\n"
"        akey \"avalue\"\n"
"}\n"
"b\n"
"\n"
"        bkey \"bvalue\"\n"
"}\n";

// counts of the respective section counts in config_example.info

const int CONFIG_N_A_SECTIONS = 1;
const int CONFIG_N_B_SECTIONS = 1;

class DummySubscriber
{
public:

  DummySubscriber(ConfigFile& config,
                  int nASections,
                  int nBSections,
                  bool expectDryRun)
    : m_nASections(nASections),
      m_nBSections(nBSections),
      m_nRemainingACallbacks(nASections),
      m_nRemainingBCallbacks(nBSections),
      m_expectDryRun(expectDryRun)
  {

  }

  void
  onA(const ConfigSection& section, bool isDryRun)
  {
    // NFD_LOG_DEBUG("a");
    BOOST_CHECK_EQUAL(isDryRun, m_expectDryRun);
    --m_nRemainingACallbacks;
  }


  void
  onB(const ConfigSection& section, bool isDryRun)
  {
    // NFD_LOG_DEBUG("b");
    BOOST_CHECK_EQUAL(isDryRun, m_expectDryRun);
    --m_nRemainingBCallbacks;
  }

  bool
  allCallbacksFired() const
  {
    return m_nRemainingACallbacks == 0 &&
      m_nRemainingBCallbacks == 0;
  }

  bool
  noCallbacksFired() const
  {
    return m_nRemainingACallbacks == m_nASections &&
      m_nRemainingBCallbacks == m_nBSections;
  }

  virtual
  ~DummySubscriber()
  {

  }

private:
  int m_nASections;
  int m_nBSections;
  int m_nRemainingACallbacks;
  int m_nRemainingBCallbacks;
  bool m_expectDryRun;
};

class DummyAllSubscriber : public DummySubscriber
{
public:
  DummyAllSubscriber(ConfigFile& config, bool expectDryRun=false)
    : DummySubscriber(config,
                      CONFIG_N_A_SECTIONS,
                      CONFIG_N_B_SECTIONS,
                      expectDryRun)
  {
    config.addSectionHandler("a", bind(&DummySubscriber::onA, this, _1, _2));
    config.addSectionHandler("b", bind(&DummySubscriber::onB, this, _1, _2));
  }

  virtual
  ~DummyAllSubscriber()
  {

  }
};

class DummyOneSubscriber : public DummySubscriber
{
public:
  DummyOneSubscriber(ConfigFile& config,
                     const std::string& sectionName,
                     bool expectDryRun=false)
    : DummySubscriber(config,
                      (sectionName == "a"),
                      (sectionName == "b"),
                      expectDryRun)
  {
    if (sectionName == "a")
      {
        config.addSectionHandler(sectionName, bind(&DummySubscriber::onA, this, _1, _2));
      }
    else if (sectionName == "b")
      {
        config.addSectionHandler(sectionName, bind(&DummySubscriber::onB, this, _1, _2));
      }
    else
      {
        BOOST_FAIL("Test setup error: "
                   << "Unexpected section name "
                   <<"\"" << sectionName << "\"");
      }

  }

  virtual
  ~DummyOneSubscriber()
  {

  }
};

class DummyNoSubscriber : public DummySubscriber
{
public:
  DummyNoSubscriber(ConfigFile& config, bool expectDryRun)
    : DummySubscriber(config, 0, 0, expectDryRun)
  {

  }

  virtual
  ~DummyNoSubscriber()
  {

  }
};

BOOST_AUTO_TEST_CASE(OnConfigStream)
{
  ConfigFile file;
  DummyAllSubscriber sub(file);
  std::ifstream input;

  input.open("tests/mgmt/config_example.info");
  BOOST_REQUIRE(input.is_open());

  file.parse(input);

  BOOST_CHECK(sub.allCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigStreamEmptyStream)
{
  ConfigFile file;
  DummyAllSubscriber sub(file);

  std::ifstream input;

  BOOST_CHECK_THROW(file.parse(input), ConfigFile::Error);
  BOOST_CHECK(sub.noCallbacksFired());
}


BOOST_AUTO_TEST_CASE(OnConfigString)
{
  ConfigFile file;
  DummyAllSubscriber sub(file);

  file.parse(CONFIG);

  BOOST_CHECK(sub.allCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigStringEmpty)
{
  ConfigFile file;
  DummyAllSubscriber sub(file);

  BOOST_CHECK_THROW(file.parse(std::string()), ConfigFile::Error);
  BOOST_CHECK(sub.noCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigStringMalformed)
{
  ConfigFile file;
  DummyAllSubscriber sub(file);

  BOOST_CHECK_THROW(file.parse(MALFORMED_CONFIG), ConfigFile::Error);
  BOOST_CHECK(sub.noCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigStringDryRun)
{
  ConfigFile file;
  DummyAllSubscriber sub(file, true);

  file.parse(CONFIG, true);

  BOOST_CHECK(sub.allCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigFilename)
{
  ConfigFile file;
  DummyAllSubscriber sub(file);

  file.parse("tests/mgmt/config_example.info");

  BOOST_CHECK(sub.allCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigFilenameNoFile)
{
  ConfigFile file;
  DummyAllSubscriber sub(file);

  BOOST_CHECK_THROW(file.parse("i_made_this_up.info"), ConfigFile::Error);

  BOOST_CHECK(sub.noCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigFilenameMalformed)
{
  ConfigFile file;
  DummyAllSubscriber sub(file);

  BOOST_CHECK_THROW(file.parse("tests/mgmt/config_malformed.info"), ConfigFile::Error);

  BOOST_CHECK(sub.noCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigStreamDryRun)
{
  ConfigFile file;
  DummyAllSubscriber sub(file, true);
  std::ifstream input;

  input.open("tests/mgmt/config_example.info");
  BOOST_REQUIRE(input.is_open());

  file.parse(input, true);

  BOOST_CHECK(sub.allCallbacksFired());

  input.close();
}

BOOST_AUTO_TEST_CASE(OnConfigFilenameDryRun)
{
  ConfigFile file;
  DummyAllSubscriber sub(file, true);

  file.parse("tests/mgmt/config_example.info", true);
  BOOST_CHECK(sub.allCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigReplaceSubscriber)
{
  ConfigFile file;
  DummyAllSubscriber sub1(file);
  DummyAllSubscriber sub2(file);

  file.parse(CONFIG);

  BOOST_CHECK(sub1.noCallbacksFired());
  BOOST_CHECK(sub2.allCallbacksFired());
}

BOOST_AUTO_TEST_CASE(OnConfigUncoveredSections)
{
  ConfigFile file;

  BOOST_CHECK_THROW(file.parse(CONFIG), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(OnConfigCoveredByPartialSubscribers)
{
  ConfigFile file;
  DummyOneSubscriber subA(file, "a");
  DummyOneSubscriber subB(file, "b");

  file.parse(CONFIG);

  BOOST_CHECK(subA.allCallbacksFired());
  BOOST_CHECK(subB.allCallbacksFired());
}

} // namespace nfd

BOOST_AUTO_TEST_SUITE_END()
