/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2017-2020, Regents of the University of California.
 *
 * This file is part of ndncert, a certificate management system based on NDN.
 *
 * ndncert 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.
 *
 * ndncert 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 copies of the GNU General Public License along with
 * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndncert authors and contributors.
 */

#include "detail/challenge-encoder.hpp"
#include "detail/error-encoder.hpp"
#include "detail/info-encoder.hpp"
#include "detail/new-renew-revoke-encoder.hpp"
#include "detail/probe-encoder.hpp"
#include "detail/ca-configuration.hpp"
#include "test-common.hpp"
#include "identity-management-fixture.hpp"

namespace ndn {
namespace ndncert {
namespace tests {

BOOST_FIXTURE_TEST_SUITE(TestProtocolEncoding, IdentityManagementTimeFixture)

BOOST_AUTO_TEST_CASE(InfoEncoding)
{
  ca::CaConfig config;
  config.load("tests/unit-tests/config-files/config-ca-1");

  requester::ProfileStorage caCache;
  caCache.load("tests/unit-tests/config-files/config-client-1");
  auto& cert = caCache.getKnownProfiles().front().m_cert;

  auto b = infotlv::encodeDataContent(config.m_caProfile, *cert);
  auto item = infotlv::decodeDataContent(b);

  BOOST_CHECK_EQUAL(*item.m_cert, *cert);
  BOOST_CHECK_EQUAL(item.m_caInfo, config.m_caProfile.m_caInfo);
  BOOST_CHECK_EQUAL(item.m_caPrefix, config.m_caProfile.m_caPrefix);
  BOOST_CHECK_EQUAL_COLLECTIONS(item.m_probeParameterKeys.begin(), item.m_probeParameterKeys.end(),
                                config.m_caProfile.m_probeParameterKeys.begin(), config.m_caProfile.m_probeParameterKeys.end());
  BOOST_CHECK_EQUAL(item.m_maxValidityPeriod, config.m_caProfile.m_maxValidityPeriod);
}

BOOST_AUTO_TEST_CASE(ErrorEncoding)
{
  std::string msg = "Just to test";
  auto b = errortlv::encodeDataContent(ErrorCode::NAME_NOT_ALLOWED, msg);
  auto item = errortlv::decodefromDataContent(b);
  BOOST_CHECK_EQUAL(std::get<0>(item), ErrorCode::NAME_NOT_ALLOWED);
  BOOST_CHECK_EQUAL(std::get<1>(item), msg);
}

BOOST_AUTO_TEST_CASE(ProbeEncodingAppParam)
{
  std::multimap<std::string, std::string> parameters;
  parameters.emplace("key1", "value1");
  parameters.emplace("key2", "value2");
  auto appParam = probetlv::encodeApplicationParameters(std::move(parameters));
  auto param1 = probetlv::decodeApplicationParameters(appParam);
  BOOST_CHECK_EQUAL(param1.size(), 2);
  BOOST_CHECK_EQUAL(param1.find("key1")->second, "value1");
  BOOST_CHECK_EQUAL(param1.find("key2")->second, "value2");
}

BOOST_AUTO_TEST_CASE(ProbeEncodingData)
{
  ca::CaConfig config;
  config.load("tests/unit-tests/config-files/config-ca-5");
  std::vector<Name> names;
  names.emplace_back("/ndn/1");
  names.emplace_back("/ndn/2");
  auto b = probetlv::encodeDataContent(names, 2, config.m_redirection);
  std::vector<std::pair<Name, int>> retNames;
  std::vector<Name> redirection;
  probetlv::decodeDataContent(b, retNames, redirection);
  BOOST_CHECK_EQUAL(retNames.size(), names.size());
  auto it1 = retNames.begin();
  auto it2 = names.begin();
  for (; it1 != retNames.end() && it2 != names.end(); it1++, it2++) {
    BOOST_CHECK_EQUAL(it1->first, *it2);
    BOOST_CHECK_EQUAL(it1->second, 2);
  }
  BOOST_CHECK_EQUAL(redirection.size(), config.m_redirection.size());
  auto it3 = redirection.begin();
  auto it4 = config.m_redirection.begin();
  for (; it3 != redirection.end() && it4 != config.m_redirection.end(); it3++, it4++) {
    BOOST_CHECK_EQUAL(*it3, (*it4)->getFullName());
  }
}

BOOST_AUTO_TEST_CASE(NewRevokeEncodingParam)
{
  requester::ProfileStorage caCache;
  caCache.load("tests/unit-tests/config-files/config-client-1");
  auto& certRequest = caCache.getKnownProfiles().front().m_cert;
  std::vector<uint8_t> pub = ECDHState().getSelfPubKey();
  auto b = requesttlv::encodeApplicationParameters(RequestType::REVOKE, pub, *certRequest);
  std::vector<uint8_t> returnedPub;
  std::shared_ptr<security::Certificate> returnedCert;
  requesttlv::decodeApplicationParameters(b, RequestType::REVOKE, returnedPub, returnedCert);

  BOOST_CHECK_EQUAL(returnedPub.size(), pub.size());
  for (auto it1 = returnedPub.begin(), it2 = pub.begin();
       it1 != returnedPub.end() && it2 != pub.end(); it1++, it2++) {
    BOOST_CHECK_EQUAL(*it1, *it2);
  }
  BOOST_CHECK_EQUAL(*returnedCert, *certRequest);
}

BOOST_AUTO_TEST_CASE(NewRevokeEncodingData)
{
  std::vector<uint8_t> pub = ECDHState().getSelfPubKey();
  std::array<uint8_t, 32> salt = {{101}};
  RequestId id = {{102}};
  std::list<std::string> list;
  list.emplace_back("abc");
  list.emplace_back("def");
  auto b = requesttlv::encodeDataContent(pub, salt, id, Status::BEFORE_CHALLENGE, list);
  std::vector<uint8_t> returnedPub;
  std::array<uint8_t, 32> returnedSalt;
  RequestId returnedId;
  Status s;
  auto retlist = requesttlv::decodeDataContent(b, returnedPub, returnedSalt, returnedId, s);
  BOOST_CHECK_EQUAL_COLLECTIONS(returnedPub.begin(), returnedPub.end(), pub.begin(), pub.end());
  BOOST_CHECK_EQUAL_COLLECTIONS(returnedSalt.begin(), returnedSalt.end(), salt.begin(), salt.end());
  BOOST_CHECK_EQUAL_COLLECTIONS(returnedId.begin(), returnedId.end(), id.begin(), id.end());
  BOOST_CHECK_EQUAL(static_cast<size_t>(s), static_cast<size_t>(Status::BEFORE_CHALLENGE));
}

BOOST_AUTO_TEST_CASE(ChallengeEncoding)
{
  const uint8_t key[] = {0x23, 0x70, 0xe3, 0x20, 0xd4, 0x34, 0x42, 0x08,
                         0xe0, 0xff, 0x56, 0x83, 0xf2, 0x43, 0xb2, 0x13};
  requester::ProfileStorage caCache;
  caCache.load("tests/unit-tests/config-files/config-client-1");
  security::Certificate certRequest = *caCache.getKnownProfiles().front().m_cert;
  RequestId id = {{102}};
  ca::RequestState state;
  state.caPrefix = Name("/ndn/ucla");
  state.requestId = id;
  state.requestType = RequestType::NEW;
  state.status = Status::PENDING;
  state.cert = certRequest;
  std::memcpy(state.encryptionKey.data(), key, sizeof(key));
  state.challengeType = "pin";
  auto tp = time::system_clock::now();
  state.challengeState = ca::ChallengeState("test", tp, 3, time::seconds(3600), JsonSection());
  auto contentBlock = challengetlv::encodeDataContent(state, Name("/ndn/ucla/a/b/c"));

  requester::RequestState context(m_keyChain, caCache.getKnownProfiles().front(), RequestType::NEW);
  context.m_requestId = id;
  std::memcpy(context.m_aesKey.data(), key, sizeof(key));
  advanceClocks(time::seconds(10));
  challengetlv::decodeDataContent(contentBlock, context);

  BOOST_CHECK_EQUAL(static_cast<size_t>(context.m_status), static_cast<size_t>(Status::PENDING));
  BOOST_CHECK_EQUAL(context.m_challengeStatus, "test");
  BOOST_CHECK_EQUAL(context.m_remainingTries, 3);
  BOOST_CHECK_EQUAL(context.m_freshBefore, tp + time::seconds(3600) + time::seconds(10));
  BOOST_CHECK_EQUAL(context.m_issuedCertName, "/ndn/ucla/a/b/c");
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace tests
} // namespace ndncert
} // namespace ndn
