/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2014 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 "security/conf/checker.hpp"
#include "security/key-chain.hpp"
#include "identity-management-fixture.hpp"
#include "boost-test.hpp"

namespace ndn {

BOOST_FIXTURE_TEST_SUITE(SecurityTestConfChecker, security::IdentityManagementFixture)

void
interestChecked(const shared_ptr<const Interest>& interest)
{
  BOOST_CHECK(true);
}

void
interestCheckFailed(const shared_ptr<const Interest>& interest,
                    const std::string& failureInfo)
{
  std::cerr << failureInfo << std::endl;
  BOOST_CHECK(false);
}

void
interestCheckedFalse(const shared_ptr<const Interest>& interest)
{
  BOOST_CHECK(false);
}

void
interestCheckFailedFalse(const shared_ptr<const Interest>& interest,
                         const std::string& failureInfo)
{
  BOOST_CHECK(true);
}

void
dataChecked(const shared_ptr<const Data>& interest)
{
  BOOST_CHECK(true);
}

void
dataCheckFailed(const shared_ptr<const Data>& interest,
                const std::string& failureInfo)
{
  std::cerr << failureInfo << std::endl;
  BOOST_CHECK(false);
}

void
dataCheckedFalse(const shared_ptr<const Data>& interest)
{
  BOOST_CHECK(false);
}

void
dataCheckFailedFalse(const shared_ptr<const Data>& interest,
                     const std::string& failureInfo)
{
  BOOST_CHECK(true);
}


BOOST_AUTO_TEST_CASE(CustomizedCheckerTest1)
{
  using security::conf::CustomizedChecker;
  using security::conf::KeyLocatorChecker;
  using security::conf::RelationKeyLocatorNameChecker;

  Name identity("/SecurityTestConfChecker/CustomizedCheckerTest1");
  BOOST_REQUIRE(addIdentity(identity, RsaKeyParams()));
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);

  Name identity2("/SecurityTestConfChecker/CustomizedCheckerTest1Wrong");
  BOOST_REQUIRE(addIdentity(identity2, RsaKeyParams()));
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);

  Name packetName("/SecurityTestConfChecker/CustomizedCheckerTest1/Data");
  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data1, identity);

  shared_ptr<Data> data2 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data2, identity2);

  shared_ptr<Interest> interest1 = make_shared<Interest>(packetName);
  m_keyChain.signByIdentity(*interest1, identity);

  shared_ptr<Interest> interest2 = make_shared<Interest>(packetName);
  m_keyChain.signByIdentity(*interest2, identity2);

  int8_t result = 0;


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerEqual1 =
    make_shared<RelationKeyLocatorNameChecker>(certName.getPrefix(-1),
                                               KeyLocatorChecker::RELATION_EQUAL);
  CustomizedChecker checker1(tlv::SignatureSha256WithRsa, keyLocatorCheckerEqual1);

  result = checker1.check(*data1,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*interest1,
                          bind(interestChecked, _1),
                          bind(interestCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*interest2,
                          bind(interestCheckedFalse, _1),
                          bind(interestCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerEqual2 =
    make_shared<RelationKeyLocatorNameChecker>(identity,
                                               KeyLocatorChecker::RELATION_EQUAL);
  CustomizedChecker checker2(tlv::SignatureSha256WithRsa, keyLocatorCheckerEqual2);

  result = checker2.check(*data1,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*interest1,
                          bind(interestCheckedFalse, _1),
                          bind(interestCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerPrefix1 =
    make_shared<RelationKeyLocatorNameChecker>(certName.getPrefix(-1),
                                               KeyLocatorChecker::RELATION_IS_PREFIX_OF);
  CustomizedChecker checker3(tlv::SignatureSha256WithRsa, keyLocatorCheckerPrefix1);

  result = checker3.check(*data1,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker3.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerPrefix2 =
    make_shared<RelationKeyLocatorNameChecker>(identity,
                                               KeyLocatorChecker::RELATION_IS_PREFIX_OF);
  CustomizedChecker checker4(tlv::SignatureSha256WithRsa, keyLocatorCheckerPrefix2);

  result = checker4.check(*data1,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker4.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerStrict1 =
    make_shared<RelationKeyLocatorNameChecker>(certName.getPrefix(-1),
                                               KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF);
  CustomizedChecker checker5(tlv::SignatureSha256WithRsa, keyLocatorCheckerStrict1);

  result = checker5.check(*data1,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker5.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerStrict2 =
    make_shared<RelationKeyLocatorNameChecker>(identity,
                                               KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF);
  CustomizedChecker checker6(tlv::SignatureSha256WithRsa, keyLocatorCheckerStrict2);

  result = checker6.check(*data1,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker6.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);
}

BOOST_AUTO_TEST_CASE(CustomizedCheckerTest2)
{
  using security::conf::CustomizedChecker;
  using security::conf::KeyLocatorChecker;
  using security::conf::RegexKeyLocatorNameChecker;

  Name identity("/SecurityTestConfChecker/CustomizedCheckerTest2");
  BOOST_REQUIRE(addIdentity(identity, RsaKeyParams()));
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);

  Name identity2("/SecurityTestConfChecker/CustomizedCheckerTest2Wrong");
  BOOST_REQUIRE(addIdentity(identity2, RsaKeyParams()));
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);

  Name packetName("/SecurityTestConfChecker/CustomizedCheckerTest2/Data");
  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data1, identity);

  shared_ptr<Data> data2 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data2, identity2);

  shared_ptr<Interest> interest1 = make_shared<Interest>(packetName);
  m_keyChain.signByIdentity(*interest1, identity);

  shared_ptr<Interest> interest2 = make_shared<Interest>(packetName);
  m_keyChain.signByIdentity(*interest2, identity2);

  int8_t result = 0;


  shared_ptr<RegexKeyLocatorNameChecker> keyLocatorCheckerRegex1 =
    make_shared<RegexKeyLocatorNameChecker>(
      Regex("^<SecurityTestConfChecker><CustomizedCheckerTest2>"));
  CustomizedChecker checker1(tlv::SignatureSha256WithRsa, keyLocatorCheckerRegex1);

  result = checker1.check(*data1,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*interest1,
                          bind(interestChecked, _1),
                          bind(interestCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*interest2,
                          bind(interestCheckedFalse, _1),
                          bind(interestCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);
}

BOOST_AUTO_TEST_CASE(CustomizedCheckerTest3)
{
  using security::conf::CustomizedChecker;
  using security::conf::KeyLocatorChecker;
  using security::conf::RegexKeyLocatorNameChecker;

  Name identity("/SecurityTestConfChecker/CustomizedCheckerTest3");
  BOOST_REQUIRE(addIdentity(identity, EcdsaKeyParams()));
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);

  Name identity2("/SecurityTestConfChecker/CustomizedCheckerTest3Wrong");
  BOOST_REQUIRE(addIdentity(identity2, EcdsaKeyParams()));
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);

  Name packetName("/SecurityTestConfChecker/CustomizedCheckerTest3/Data");
  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data1, identity);

  shared_ptr<Data> data2 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data2, identity2);

  shared_ptr<Interest> interest1 = make_shared<Interest>(packetName);
  m_keyChain.signByIdentity(*interest1, identity);

  shared_ptr<Interest> interest2 = make_shared<Interest>(packetName);
  m_keyChain.signByIdentity(*interest2, identity2);

  int8_t result = 0;


  shared_ptr<RegexKeyLocatorNameChecker> keyLocatorCheckerRegex1 =
    make_shared<RegexKeyLocatorNameChecker>(
      Regex("^<SecurityTestConfChecker><CustomizedCheckerTest3>"));
  CustomizedChecker checker1(tlv::SignatureSha256WithEcdsa, keyLocatorCheckerRegex1);

  result = checker1.check(*data1,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*interest1,
                          bind(interestChecked, _1),
                          bind(interestCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*interest2,
                          bind(interestCheckedFalse, _1),
                          bind(interestCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  CustomizedChecker checker2(tlv::SignatureSha256WithRsa, keyLocatorCheckerRegex1);

  result = checker2.check(*data1,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);
}

BOOST_AUTO_TEST_CASE(HierarchicalCheckerTest1)
{
  using security::conf::HierarchicalChecker;

  Name identity("/SecurityTestConfChecker/HierarchicalCheckerTest1");
  BOOST_REQUIRE(addIdentity(identity, EcdsaKeyParams()));
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);

  Name identity2("/SecurityTestConfChecker/HierarchicalCheckerTest1/Data");
  BOOST_REQUIRE(addIdentity(identity2, RsaKeyParams()));
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);

  Name packetName("/SecurityTestConfChecker/HierarchicalCheckerTest1/Data");
  Name packetName2("/SecurityTestConfChecker");
  Name packetName3("/SecurityTestConfChecker/HierarchicalCheckerTest1");

  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data1, identity);

  shared_ptr<Data> data2 = make_shared<Data>(packetName2);
  m_keyChain.signByIdentity(*data2, identity);

  shared_ptr<Data> data3 = make_shared<Data>(packetName3);
  m_keyChain.signByIdentity(*data3, identity);

  shared_ptr<Data> data4 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data4, identity2);

  shared_ptr<Data> data5 = make_shared<Data>(packetName2);
  m_keyChain.signByIdentity(*data5, identity2);

  shared_ptr<Data> data6 = make_shared<Data>(packetName3);
  m_keyChain.signByIdentity(*data6, identity2);

  int8_t result = 0;

  HierarchicalChecker checker1(tlv::SignatureSha256WithEcdsa);

  result = checker1.check(*data1,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*data3,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data4,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*data5,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*data6,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  HierarchicalChecker checker2(tlv::SignatureSha256WithRsa);

  result = checker2.check(*data1,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data3,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data4,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 0);

  result = checker2.check(*data5,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data6,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);
}

BOOST_AUTO_TEST_CASE(FixedSignerCheckerTest1)
{
  using security::conf::FixedSignerChecker;

  Name identity("/SecurityTestConfChecker/FixedSignerCheckerTest1");
  BOOST_REQUIRE(addIdentity(identity, EcdsaKeyParams()));
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
  shared_ptr<IdentityCertificate> cert1 = m_keyChain.getCertificate(certName);

  Name identity2("/SecurityTestConfChecker/FixedSignerCheckerTest1Wrong");
  BOOST_REQUIRE(addIdentity(identity2, RsaKeyParams()));
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);
  shared_ptr<IdentityCertificate> cert2 = m_keyChain.getCertificate(certName2);

  Name packetName("/Test/Data");

  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data1, identity);

  shared_ptr<Data> data2 = make_shared<Data>(packetName);
  m_keyChain.signByIdentity(*data2, identity2);

  std::vector<shared_ptr<IdentityCertificate> > certSet1;
  certSet1.push_back(cert1);

  std::vector<shared_ptr<IdentityCertificate> > certSet2;
  certSet2.push_back(cert2);


  int8_t result = 0;

  FixedSignerChecker checker1(tlv::SignatureSha256WithEcdsa, certSet1);

  result = checker1.check(*data1,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 1);

  result = checker1.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  FixedSignerChecker checker2(tlv::SignatureSha256WithRsa, certSet1);

  result = checker2.check(*data1,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  FixedSignerChecker checker3(tlv::SignatureSha256WithEcdsa, certSet2);

  result = checker3.check(*data1,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker3.check(*data2,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);


  FixedSignerChecker checker4(tlv::SignatureSha256WithRsa, certSet2);

  result = checker4.check(*data1,
                          bind(dataCheckedFalse, _1),
                          bind(dataCheckFailedFalse, _1, _2));
  BOOST_CHECK_EQUAL(result, -1);

  result = checker4.check(*data2,
                          bind(dataChecked, _1),
                          bind(dataCheckFailed, _1, _2));
  BOOST_CHECK_EQUAL(result, 1);
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace ndn
