/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2016,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD 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.
 *
 * NFD 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
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mgmt/strategy-choice-manager.hpp"

#include "core/random.hpp"
#include "face/face.hpp"
#include "face/internal-face.hpp"
#include "fw/strategy.hpp"
#include "table/name-tree.hpp"
#include "table/strategy-choice.hpp"

#include "nfd-manager-common-fixture.hpp"
#include "../fw/dummy-strategy.hpp"
#include "../fw/choose-strategy.hpp"

#include <ndn-cxx/mgmt/nfd/strategy-choice.hpp>

namespace nfd {
namespace tests {

class StrategyChoiceManagerFixture : public NfdManagerCommonFixture
{
public:
  StrategyChoiceManagerFixture()
    : m_strategyChoice(m_forwarder.getStrategyChoice())
    , m_manager(m_strategyChoice, m_dispatcher, *m_authenticator)
  {
    setTopPrefix();
    setPrivilege("strategy-choice");
  }

public:
  void
  installStrategy(const Name& strategyName)
  {
    // install<DummyStrategy>(m_forwarder, strategyName);
  }

  const Name&
  findStrategy(const Name& name)
  {
    return m_strategyChoice.findEffectiveStrategy(name).getInstanceName();
  }

  ControlParameters
  makeParameters(const Name& name, const Name& strategy)
  {
    return ControlParameters().setName(name).setStrategy(strategy);
  }

protected:
  StrategyChoice& m_strategyChoice;
  StrategyChoiceManager m_manager;
};

BOOST_AUTO_TEST_SUITE(Mgmt)
BOOST_FIXTURE_TEST_SUITE(TestStrategyChoiceManager, StrategyChoiceManagerFixture)

///\todo #3868 rewrite test case after changing strategy versioning scheme
BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(SetStrategy, 7)
BOOST_AUTO_TEST_CASE(SetStrategy)
{
  auto testSetStrategy = [this] (const ControlParameters& parameters) -> Name {
    m_responses.clear();
    auto command = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", parameters);
    receiveInterest(command);
    return command->getName();
  };

  installStrategy("/localhost/nfd/strategy/test-strategy-a");
  installStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%01"); // version 1
  installStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02"); // version 2

  auto parametersA  = makeParameters("test", "/localhost/nfd/strategy/test-strategy-a");
  auto parametersB  = makeParameters("test", "/localhost/nfd/strategy/test-strategy-b");
  auto parametersC1 = makeParameters("test", "/localhost/nfd/strategy/test-strategy-c/%FD%01");
  auto parametersC  = makeParameters("test", "/localhost/nfd/strategy/test-strategy-c");

  auto commandNameA = testSetStrategy(parametersA); // succeed
  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, commandNameA, makeResponse(200, "OK", parametersA)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-a");

  auto commandNameB = testSetStrategy(parametersB); // not installed
  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, commandNameB, ControlResponse(504, "Unsupported strategy")),
                    CheckResponseResult::OK);

  auto commandNameC1 = testSetStrategy(parametersC1); // specified version
  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, commandNameC1, makeResponse(200, "OK", parametersC1)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-c/%FD%01");

  auto commandNameC = testSetStrategy(parametersC); // latest version
  parametersC.setStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02"); // change to latest
  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, commandNameC, makeResponse(200, "OK", parametersC)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-c/%FD%02");
}

///\todo #3868 rewrite test case after changing strategy versioning scheme
BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(UnsetStrategy, 9)
BOOST_AUTO_TEST_CASE(UnsetStrategy)
{
  auto testUnsetStrategy = [this] (const ControlParameters& parameters) -> Name {
    m_responses.clear();
    auto command = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", parameters);
    receiveInterest(command);
    return command->getName();
  };

  installStrategy("/localhost/nfd/strategy/test-strategy-a");
  installStrategy("/localhost/nfd/strategy/test-strategy-b");
  installStrategy("/localhost/nfd/strategy/test-strategy-c");

  BOOST_CHECK(m_strategyChoice.insert("ndn:/", "/localhost/nfd/strategy/test-strategy-a")); // root
  BOOST_CHECK(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b")); // test
  BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a");

  auto parametersRoot = ControlParameters().setName("ndn:/"); // root prefix
  auto parametersNone = ControlParameters().setName("/none"); // no such entry
  auto parametersTest = ControlParameters().setName("/test"); // has such entry

  BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a"); // root
  auto commandRootName = testUnsetStrategy(parametersRoot);
  auto expectedResponse = ControlResponse(400, "failed in validating parameters");
  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, commandRootName, expectedResponse), CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a"); // keep as root

  BOOST_CHECK_EQUAL(findStrategy("/none"), "/localhost/nfd/strategy/test-strategy-a"); // root
  auto commandNoneName = testUnsetStrategy(parametersNone);
  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, commandNoneName, makeResponse(200, "OK", parametersNone)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(findStrategy("/none"), "/localhost/nfd/strategy/test-strategy-a"); // root

  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-b"); // self
  auto commandTestName = testUnsetStrategy(parametersTest);
  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, commandTestName, makeResponse(200, "OK", parametersTest)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-a"); // parent
}

// @todo Remove when ndn::nfd::StrategyChoice implements operator!= and operator<<
class StrategyChoice : public ndn::nfd::StrategyChoice
{
public:
  StrategyChoice() = default;

  StrategyChoice(const ndn::nfd::StrategyChoice& entry)
    : ndn::nfd::StrategyChoice(entry)
  {
  }
};

bool
operator!=(const StrategyChoice& left, const StrategyChoice& right)
{
  return left.getName() != right.getName() || left.getStrategy() != right.getStrategy();
}

std::ostream&
operator<<(std::ostream &os, const StrategyChoice& entry)
{
  os << "[ " << entry.getName() << ", " << entry.getStrategy() << " ]";
  return os;
}

///\todo #3868 rewrite test case after changing strategy versioning scheme
BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(StrategyChoiceDataset, 4)
BOOST_AUTO_TEST_CASE(StrategyChoiceDataset)
{
  size_t nPreInsertedStrategies = m_strategyChoice.size(); // the best-route strategy
  std::set<Name> actualNames, actualStrategies;
  for (const auto& entry : m_strategyChoice) {
    actualNames.insert(entry.getPrefix());
    actualStrategies.insert(entry.getStrategyInstanceName());
  }

  std::uniform_int_distribution<uint64_t> dist;
  size_t nEntries = 1024;
  for (size_t i = 0 ; i < nEntries ; i++) {
    auto name = Name("test-name").appendSegment(i);
    auto strategy = Name("test-strategy").appendSegment(dist(getGlobalRng()));
    auto entry = ndn::nfd::StrategyChoice().setName(name).setStrategy(strategy);
    actualNames.insert(name);
    actualStrategies.insert(strategy);
    installStrategy(strategy);
    m_strategyChoice.insert(name, strategy);
  }
  nEntries += nPreInsertedStrategies;

  receiveInterest(makeInterest("/localhost/nfd/strategy-choice/list"));

  Block content;
  BOOST_CHECK_NO_THROW(content = concatenateResponses());
  BOOST_CHECK_NO_THROW(content.parse());
  BOOST_CHECK_EQUAL(content.elements().size(), nEntries);

  std::vector<StrategyChoice> receivedRecords, expectedRecords;
  for (size_t idx = 0; idx < nEntries; ++idx) {
    BOOST_TEST_MESSAGE("processing element: " << idx);

    StrategyChoice decodedEntry;
    //BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
    receivedRecords.push_back(decodedEntry);

    actualNames.erase(decodedEntry.getName());
    actualStrategies.erase(decodedEntry.getStrategy());

    auto result = m_strategyChoice.get(decodedEntry.getName());
    BOOST_REQUIRE(result.first);

    auto record = StrategyChoice().setName(decodedEntry.getName()).setStrategy(result.second);
    expectedRecords.push_back(record);
  }

  BOOST_CHECK_EQUAL(actualNames.size(), 0);
  BOOST_CHECK_EQUAL(actualStrategies.size(), 0);
  BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
                                expectedRecords.begin(), expectedRecords.end());
}

BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoiceManager
BOOST_AUTO_TEST_SUITE_END() // Mgmt

} // namespace tests
} // namespace nfd
