/* -*- 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/info-encoder.hpp"
#include "detail/probe-encoder.hpp"
#include "detail/new-renew-revoke-encoder.hpp"
#include "detail/challenge-encoder.hpp"
#include "test-common.hpp"

namespace ndn {
namespace ndncert {
namespace tests {

BOOST_FIXTURE_TEST_SUITE(TestProtocolDetail, IdentityManagementTimeFixture)

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

  const auto& identity = addIdentity("/test");
  const auto& cert = identity.getDefaultKey().getDefaultCertificate();
  auto encoded = InfoEncoder::encodeDataContent(config.m_caItem, cert);
  auto decoded = InfoEncoder::decodeDataContent(encoded);
  BOOST_CHECK_EQUAL(config.m_caItem.m_caPrefix, decoded.m_caPrefix);
  BOOST_CHECK_EQUAL(config.m_caItem.m_caInfo, decoded.m_caInfo);
  BOOST_CHECK_EQUAL(config.m_caItem.m_maxValidityPeriod, decoded.m_maxValidityPeriod);
  BOOST_CHECK_EQUAL(config.m_caItem.m_probeParameterKeys.size(), decoded.m_probeParameterKeys.size());
  BOOST_CHECK_EQUAL(config.m_caItem.m_probeParameterKeys.front(), decoded.m_probeParameterKeys.front());
  BOOST_CHECK_EQUAL(cert.wireEncode(), decoded.m_cert->wireEncode());
}

BOOST_AUTO_TEST_CASE(TestProbe)
{
  std::vector<std::tuple<std::string, std::string>> parameters;
  parameters.push_back(std::make_tuple("email", "zhiyi@cs.ucla.edu"));
  auto appParametersTlv = ProbeEncoder::encodeApplicationParameters(std::move(parameters));
  auto decodedParameters = ProbeEncoder::decodeApplicationParameters(appParametersTlv);
  BOOST_CHECK_EQUAL(std::get<0>(decodedParameters[0]), "email");
  BOOST_CHECK_EQUAL(std::get<1>(decodedParameters[0]), "zhiyi@cs.ucla.edu");
  BOOST_CHECK_EQUAL(decodedParameters.size(), 1);

  ca::CaConfig config;
  config.load("tests/unit-tests/config-files/config-ca-5");
  std::vector<Name> ids;
  ids.push_back(Name("/example"));
  auto contentTlv = ProbeEncoder::encodeDataContent(ids, 2, config.m_redirection);
  std::vector<Name> decodedRedirectionItems;
  std::vector<std::pair<Name, int>> decodedIds;
  ProbeEncoder::decodeDataContent(contentTlv, decodedIds, decodedRedirectionItems);
  BOOST_CHECK_EQUAL(decodedIds[0].first, Name("/example"));
  BOOST_CHECK_EQUAL(decodedIds[0].second, 2);
  BOOST_CHECK_EQUAL(decodedRedirectionItems[0], config.m_redirection->at(0)->getFullName());
}

BOOST_AUTO_TEST_CASE(TestNewRenewRevoke)
{
  auto identity = addIdentity(Name("/ndn"));
  auto key = identity.getDefaultKey();
  auto cert = key.getDefaultCertificate();

  ECDHState ecdhState;
  auto selfKey = ecdhState.getSelfPubKey();
  auto block = NewRenewRevokeEncoder::encodeApplicationParameters(RequestType::NEW, selfKey, cert);
  std::vector<uint8_t> peerKey;
  shared_ptr<security::Certificate> clientCert;
  NewRenewRevokeEncoder::decodeApplicationParameters(block, RequestType::NEW, peerKey, clientCert);
  BOOST_CHECK_EQUAL_COLLECTIONS(selfKey.begin(), selfKey.end(), peerKey.begin(), peerKey.end());
  BOOST_CHECK_EQUAL(cert, *clientCert);

  block = NewRenewRevokeEncoder::encodeApplicationParameters(RequestType::REVOKE, selfKey, cert);
  NewRenewRevokeEncoder::decodeApplicationParameters(block, RequestType::REVOKE, peerKey, clientCert);
  BOOST_CHECK_EQUAL_COLLECTIONS(selfKey.begin(), selfKey.end(), peerKey.begin(), peerKey.end());
  BOOST_CHECK_EQUAL(cert, *clientCert);

  // NewRenewRevokeEncoder::encodeDataContent(ecdhState.getBase64PubKey(), "")
}

BOOST_AUTO_TEST_SUITE_END() // TestProtocolDetail

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