/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2018, 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-common.hpp"
#include "dummy-forwarder.hpp"
#include "static-data.hpp"

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

namespace ndn {
namespace nac {
namespace tests {

class StaticDataEnvironment : public UnitTestTimeFixture
{
public:
  StaticDataEnvironment()
    : fw(m_io, m_keyChain)
    , imsFace(static_cast<util::DummyClientFace&>(fw.addFace()))
  {
    StaticData data;
    for (const auto& block : data.managerPackets) {
      auto data = make_shared<Data>(block);
      m_ims.insert(*data);
    }

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

public:
  DummyForwarder fw;
  util::DummyClientFace& imsFace;
  InMemoryStoragePersistent m_ims;
};

class EncryptorFixture : public StaticDataEnvironment
{
public:
  EncryptorFixture()
    : face(static_cast<util::DummyClientFace&>(fw.addFace()))
    , encryptor("/access/policy/identity/NAC/dataset", "/some/ck/prefix", signingWithSha256(),
                [] (auto&&...) {},
                validator, m_keyChain, face)
  {
    advanceClocks(1_ms, 10);
  }

public:
  util::DummyClientFace& face;
  ValidatorNull validator;
  Encryptor encryptor;
};

BOOST_FIXTURE_TEST_SUITE(TestEncryptor, EncryptorFixture)

BOOST_AUTO_TEST_CASE(EncryptAndPublishedCk)
{
  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 = 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_AUTO_TEST_CASE(EnumerateDataFromIms)
{
  encryptor.regenerateCk([] (auto&&...) {});
  advanceClocks(1_ms, 10);

  encryptor.regenerateCk([] (auto&&...) {});
  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(DumpPackets) // use this to update content of other test cases
{
  if (std::getenv("NAC_DUMP_PACKETS") == nullptr) {
    return;
  }

  std::string plaintext = "Data to encrypt";

  std::cerr << "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().wire(), block.wireEncode().size(), true);
    if (i < 2) {
      std::cerr << "\"_block,\n";
    }
    else {
      std::cerr << "\"_block\n";
    }

    encryptor.regenerateCk([] (auto&&...) {});
    advanceClocks(1_ms, 10);
  }
  std::cerr  << "  };\n\n";

  std::cerr << "std::vector<Block> encryptorPackets = {\n";
  size_t i = 0;
  for (const auto& data : encryptor) {
    std::cerr << "    \"";
    printHex(std::cerr, data.wireEncode().wire(), data.wireEncode().size(), true);

    if (i < encryptor.size() - 1) {
      std::cerr << "\"_block,\n";
    }
    else {
      std::cerr << "\"_block\n";
    }

    ++i;
  }
  std::cerr  << "  };\n\n";
}

BOOST_AUTO_TEST_SUITE_END()

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