/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022, Regents of the University of California
 *
 * NAC library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * NAC library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of NAC library authors and contributors.
 */

#include "encryptor.hpp"

#include "tests/boost-test.hpp"
#include "tests/io-key-chain-fixture.hpp"
#include "tests/unit/static-data.hpp"

#include <iostream>
#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/util/string-helper.hpp>

namespace ndn {
namespace nac {
namespace tests {

class EncryptorStaticDataEnvironment : public IoKeyChainFixture
{
public:
  EncryptorStaticDataEnvironment(bool shouldPublishData)
  {
    if (shouldPublishData) {
      publishData();
    }

    auto serveFromIms = [this] (const Name&, const Interest& interest) {
      auto data = m_ims.find(interest);
      if (data != nullptr) {
        m_imsFace.put(*data);
      }
    };
    m_imsFace.setInterestFilter("/", serveFromIms, [] (auto...) {});
    advanceClocks(1_ms, 10);

    m_imsFace.sentData.clear();
    m_imsFace.sentInterests.clear();
  }

  void
  publishData()
  {
    StaticData data;
    for (const auto& block : data.managerPackets) {
      m_ims.insert(*make_shared<Data>(block));
    }
    advanceClocks(1_ms, 10);
  }

protected:
  util::DummyClientFace m_imsFace{m_io, m_keyChain, {true, true}};

private:
  InMemoryStoragePersistent m_ims;
};

template<bool shouldPublishData = true>
class EncryptorFixture : public EncryptorStaticDataEnvironment
{
public:
  EncryptorFixture()
    : EncryptorStaticDataEnvironment(shouldPublishData)
    , face(m_io, m_keyChain, {true, true})
    , encryptor("/access/policy/identity/NAC/dataset", "/some/ck/prefix", signingWithSha256(),
                [=] (const ErrorCode& code, const std::string& error) {
                  onFailure(code, error);
                },
                validator, m_keyChain, face)
  {
    face.linkTo(m_imsFace);
    advanceClocks(1_ms, 10);
  }

public:
  util::DummyClientFace face;
  ValidatorNull validator;
  Encryptor encryptor;
  util::Signal<EncryptorFixture, ErrorCode, std::string> onFailure;
};

BOOST_FIXTURE_TEST_SUITE(TestEncryptor, EncryptorFixture<>)

BOOST_AUTO_TEST_CASE(EncryptAndPublishedCk)
{
  encryptor.m_kek.reset();
  BOOST_CHECK_EQUAL(encryptor.m_isKekRetrievalInProgress, false);
  encryptor.regenerateCk();
  BOOST_CHECK_EQUAL(encryptor.m_isKekRetrievalInProgress, true);

  const std::string plaintext = "Data to encrypt";
  auto block = encryptor.encrypt({reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size()});

  EncryptedContent content(block);
  auto ckPrefix = content.getKeyLocator();
  BOOST_CHECK_EQUAL(ckPrefix.getPrefix(-1), "/some/ck/prefix/CK");

  BOOST_CHECK(content.hasIv());
  BOOST_CHECK_NE(std::string(reinterpret_cast<const char*>(content.getPayload().value()),
                             content.getPayload().value_size()),
                 plaintext);

  advanceClocks(1_ms, 10);

  // check that KEK interests has been sent
  BOOST_CHECK_EQUAL(face.sentInterests.at(0).getName().getPrefix(6),
                    Name("/access/policy/identity/NAC/dataset/KEK"));

  auto kek = m_imsFace.sentData.at(0);
  BOOST_CHECK_EQUAL(kek.getName().getPrefix(6), Name("/access/policy/identity/NAC/dataset/KEK"));
  BOOST_CHECK_EQUAL(kek.getName().size(), 7);

  face.sentData.clear();
  face.sentInterests.clear();

  face.receive(Interest(ckPrefix)
               .setCanBePrefix(true).setMustBeFresh(true));
  advanceClocks(1_ms, 10);

  auto ckName = face.sentData.at(0).getName();
  BOOST_CHECK_EQUAL(ckName.getPrefix(4), "/some/ck/prefix/CK");
  BOOST_CHECK_EQUAL(ckName.get(5), name::Component("ENCRYPTED-BY"));

  auto extractedKek = ckName.getSubName(6);
  BOOST_CHECK_EQUAL(extractedKek, kek.getName());

  BOOST_CHECK_EQUAL(encryptor.m_isKekRetrievalInProgress, false);
}

BOOST_FIXTURE_TEST_CASE(KekRetrievalFailure, EncryptorFixture<false>)
{
  size_t nErrors = 0;
  onFailure.connect([&] (auto&&...) { ++nErrors; });

  const std::string plaintext = "Data to encrypt";
  auto block = encryptor.encrypt({reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size()});
  advanceClocks(1_ms, 10);

  // check that KEK interests has been sent
  BOOST_CHECK_EQUAL(face.sentInterests.at(0).getName().getPrefix(6), Name("/access/policy/identity/NAC/dataset/KEK"));

  // and failed
  BOOST_CHECK_EQUAL(m_imsFace.sentData.size(), 0);

  advanceClocks(1_s, 13); // 4_s default interest lifetime x 3
  BOOST_CHECK_EQUAL(nErrors, 1);
  BOOST_CHECK_EQUAL(m_imsFace.sentData.size(), 0);

  advanceClocks(1_s, 730); // 60 seconds between attempts + ~12 seconds for each attempt
  BOOST_CHECK_EQUAL(nErrors, 11);
  BOOST_CHECK_EQUAL(m_imsFace.sentData.size(), 0);

  // check recovery

  publishData();

  advanceClocks(1_s, 73);

  auto kek = m_imsFace.sentData.at(0);
  BOOST_CHECK_EQUAL(kek.getName().getPrefix(6), Name("/access/policy/identity/NAC/dataset/KEK"));
  BOOST_CHECK_EQUAL(kek.getName().size(), 7);
}

BOOST_AUTO_TEST_CASE(EnumerateDataFromIms)
{
  encryptor.regenerateCk();
  advanceClocks(1_ms, 10);

  encryptor.regenerateCk();
  advanceClocks(1_ms, 10);

  BOOST_CHECK_EQUAL(encryptor.size(), 3);
  size_t nCk = 0;
  for (const auto& data : encryptor) {
    BOOST_TEST_MESSAGE(data.getName());
    if (data.getName().getPrefix(4) == Name("/some/ck/prefix/CK")) {
      ++nCk;
    }
  }
  BOOST_CHECK_EQUAL(nCk, 3);
}

BOOST_AUTO_TEST_CASE(GenerateTestData,
  * ut::description("regenerates the static test data used by other test cases")
  * ut::disabled())
{
  const auto plaintext = "Data to encrypt"s;

  std::cerr << "const std::vector<Block> encryptedBlobs = {\n";
  for (size_t i = 0; i < 3; ++i) {
    std::cerr << "  \"";
    auto block = encryptor.encrypt({reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size()});
    printHex(std::cerr, block.wireEncode(), true);
    std::cerr << "\"_block,\n";

    encryptor.regenerateCk();
    advanceClocks(1_ms, 10);
  }
  std::cerr << "};\n\n";

  std::cerr << "const std::vector<Block> encryptorPackets = {\n";
  for (const auto& data : encryptor) {
    std::cerr << "  \"";
    printHex(std::cerr, data.wireEncode(), true);
    std::cerr << "\"_block,\n";
  }
  std::cerr << "};\n\n";
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace tests
} // namespace nac
} // namespace ndn
