/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2023 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx 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.
 *
 * ndn-cxx 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 ndn-cxx authors and contributors.
 */

#include "ndn-cxx/security/validation-policy-simple-hierarchy.hpp"

#include "tests/boost-test.hpp"
#include "tests/unit/security/validator-fixture.hpp"

#include <boost/mpl/vector.hpp>

namespace ndn::tests {

BOOST_AUTO_TEST_SUITE(Security)
BOOST_FIXTURE_TEST_SUITE(TestValidationPolicySimpleHierarchy,
                         HierarchicalValidatorFixture<security::ValidationPolicySimpleHierarchy>)

using Packets = boost::mpl::vector<InterestV03Pkt, DataPkt>;

BOOST_AUTO_TEST_CASE_TEMPLATE(Validate, Packet, Packets)
{
  const Name name = "/Security/ValidatorFixture/Sub1/Sub2/Packet";

  auto packet = Packet::makePacket(name);
  VALIDATE_FAILURE(packet, "Unsigned");
  BOOST_TEST((lastError.getCode() == ValidationError::MALFORMED_SIGNATURE || // Interest
              lastError.getCode() == ValidationError::INVALID_KEY_LOCATOR)); // Data

  packet = Packet::makePacket(name);
  m_keyChain.sign(packet, signingWithSha256());
  VALIDATE_FAILURE(packet, "Should not be accepted, name not prefix of /localhost/identity/digest-sha256");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);

  packet = Packet::makePacket("/localhost/identity/digest-sha256/foobar");
  m_keyChain.sign(packet, signingWithSha256());
  VALIDATE_SUCCESS(packet, "Should be accepted, as name is prefix of /localhost/identity/digest-sha256");

  packet = Packet::makePacket(name);
  m_keyChain.sign(packet, signingByIdentity(identity));
  VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the anchor");

  packet = Packet::makePacket(name);
  m_keyChain.sign(packet, signingByIdentity(subIdentity));
  VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the policy-compliant cert");

  packet = Packet::makePacket(name);
  m_keyChain.sign(packet, signingByIdentity(otherIdentity));
  VALIDATE_FAILURE(packet, "Should fail, as signed by the policy-violating cert");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);

  packet = Packet::makePacket(name);
  m_keyChain.sign(packet, signingByIdentity(subSelfSignedIdentity));
  VALIDATE_FAILURE(packet, "Should fail, because subSelfSignedIdentity is not a trust anchor");
  BOOST_TEST(lastError.getCode() == ValidationError::LOOP_DETECTED);

  // TODO add checks with malformed packets
}

BOOST_AUTO_TEST_CASE(CertNameInKeyLocator)
{
//  auto cert = identity.getDefaultKey().getDefaultCertificate().wireEncode();
//  std::cerr << "Certificate idCert{\"" << toHex(cert) << "\"_block};" << std::endl;

//  cert = subIdentity.getDefaultKey().getDefaultCertificate().wireEncode();
//  std::cerr << "Certificate subIdCert{\"" << toHex(cert) << "\"_block};" << std::endl;

//  Data pkt("/Security/ValidatorFixture/Sub1/Sub2/Packet");
//  m_keyChain.sign(pkt, signingByIdentity(subIdentity));
//  std::cerr << "Data packet{\"" << toHex(pkt.wireEncode()) << "\"_block};" << std::endl;

  // These are hard-coded with a key locator that is the exact name of the certificate
  Certificate idCert{"06FD014C073C08085365637572697479081056616C696461746F724669787475726508034B455"
      "9080816971C408D162A0A080473656C660809FD000001499D598CA0140918010219040036EE80155B30593013060"
      "72A8648CE3D020106082A8648CE3D03010703420004F795BB9A7D51ECC4491605D49ADFCB46598D8260F872F0F15"
      "15FA4EA7259F2A27C25B5ADAFA8D548C5FA0FBB88AB7769E986057FCAB52C7AF17A7964C47DF57B165C1B01031C2"
      "D072B08085365637572697479081056616C696461746F724669787475726508034B4559080816971C408D162A0AF"
      "D00FD26FD00FE0F313937303031303154303030303030FD00FF0F323033343131303654303533353332174630440"
      "2200E9C538FE7285B006476C86F1CCCEC4398C939D1F6CE2E4F3537EB145252EE1502201A1C50E647CAF90CAA76A"
      "065452D1D560E5BB7122A7553002E7DFBCA80FCB422"_block};
  Certificate subIdCert{"06FD0188074408085365637572697479081056616C696461746F7246697874757265080453"
      "75623108034B45590808D76A31B01E14092B0806706172656E740809FD000001499D598CA0140918010219040036"
      "EE80155B3059301306072A8648CE3D020106082A8648CE3D0301070342000441783BEDE80DEF6F2910D78E1BD0AD"
      "7EF033A62F510A7578D1FC8F7601AC2B7709B27BBF225423A865964FA523B9746169FDB03C68B2FAC8D75DA0C755"
      "8122AF16901B01031C3E073C08085365637572697479081056616C696461746F724669787475726508034B455908"
      "0816971C408D162A0A080473656C660809FD000001499D598CA0FD00FD26FD00FE0F323031343131313154303533"
      "353332FD00FF0F323033343131303654303533353332FD01021FFD02001BFD02010474797065FD02020F7375622D"
      "636572746966696361746517463044022013CEFBF0E15EA6C85B26C56B550316A8A0F6F45510CCBDA4188E7732EF"
      "1E81B6022026BDC1B6F32BE163F20E379B86EF686F5B8B2B57B6494DE89D5D503C8E3C6125"_block};
  Data packet{"06CD073008085365637572697479081056616C696461746F724669787475726508045375623108045375"
      "623208065061636B657414001500164B1B01031C46074408085365637572697479081056616C696461746F724669"
      "787475726508045375623108034B45590808D76A31B01E14092B0806706172656E740809FD000001499D598CA017"
      "483046022100BDD3E0EF2385658825EB73E87A02D1A16AA8ACE50840C1B91782836164AACA3B0221008007B3EBA9"
      "B7638BD204766B08AF6E4221CDB88156CC7DA13CD916610D6D3AED"_block};

  BOOST_REQUIRE_EQUAL(packet.getKeyLocator().value().getName(),
                      "/Security/ValidatorFixture/Sub1/KEY/%D7j1%B0%1E%14%09%2B/parent/%FD%00%00%01I%9DY%8C%A0");

  this->cache.insert(idCert);
  this->cache.insert(subIdCert);
  this->validator.loadAnchor("", std::move(idCert));

  VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the policy-compliant cert");
}

BOOST_AUTO_TEST_SUITE_END() // TestValidationPolicySimpleHierarchy
BOOST_AUTO_TEST_SUITE_END() // Security

} // namespace ndn::tests
