/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2018, Regents of the University of California.
 *
 * This file is part of NDNS (Named Data Networking Domain Name Service).
 * See AUTHORS.md for complete list of NDNS authors and contributors.
 *
 * NDNS 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.
 *
 * NDNS 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 a copy of the GNU General Public License along with
 * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "daemon/rrset-factory.hpp"

#include "test-common.hpp"
#include "mgmt/management-tool.hpp"

#include <boost/lexical_cast.hpp>
#include <ndn-cxx/security/verification-helpers.hpp>

namespace ndn {
namespace ndns {
namespace tests {

NDNS_LOG_INIT(RrsetFactoryTest);

class RrsetFactoryFixture : public IdentityManagementFixture
{
public:
  RrsetFactoryFixture()
    : TEST_DATABASE2(TEST_CONFIG_PATH "/" "test-ndns.db"),
      TEST_IDENTITY_NAME("/rrest/factory"),
      TEST_CERT(TEST_CONFIG_PATH "/" "anchors/root.cert"),
      m_session(TEST_DATABASE2.string()),
      m_zoneName(TEST_IDENTITY_NAME)
  {
    Zone zone1;
    zone1.setName(m_zoneName);
    zone1.setTtl(time::seconds(4600));
    BOOST_CHECK_NO_THROW(m_session.insert(zone1));

    Name identityName = Name(TEST_IDENTITY_NAME).append("NDNS");

    m_identity = this->addIdentity(identityName);
    m_cert = m_identity.getDefaultKey().getDefaultCertificate();
    m_certName = m_cert.getName();
    saveIdentityCertificate(m_identity, TEST_CERT.string());

    NDNS_LOG_INFO("save test root cert " << m_certName << " to: " << TEST_CERT.string());
    BOOST_CHECK_GT(m_certName.size(), 0);
    NDNS_LOG_TRACE("test certName: " << m_certName);
  }

  ~RrsetFactoryFixture()
  {
    m_session.close();
    boost::filesystem::remove(TEST_DATABASE2);
    NDNS_LOG_INFO("remove database " << TEST_DATABASE2);
    boost::filesystem::remove(TEST_CERT);
  }

public:
  const boost::filesystem::path TEST_DATABASE2;
  const Name TEST_IDENTITY_NAME;
  const boost::filesystem::path TEST_CERT;
  ndns::DbMgr m_session;
  Name m_zoneName;
  Name m_certName;
  Identity m_identity;
  Certificate m_cert;
};

BOOST_FIXTURE_TEST_SUITE(RrsetFactoryTest,  RrsetFactoryFixture)

BOOST_AUTO_TEST_CASE(CheckZoneKey)
{
  // zone throws check: zone not exists
  RrsetFactory rf1(TEST_DATABASE2, "/not/exist/zone", m_keyChain, m_certName);
  BOOST_CHECK_THROW(rf1.checkZoneKey(), ndns::RrsetFactory::Error);

  // cert throws check: !matchCertificate
  RrsetFactory rf2(TEST_DATABASE2, m_zoneName, m_keyChain, "wrongCert");
  BOOST_CHECK_THROW(rf2.checkZoneKey(), std::runtime_error);

  RrsetFactory rf3(TEST_DATABASE2, m_zoneName, m_keyChain, m_certName);
  BOOST_CHECK_NO_THROW(rf3.checkZoneKey());
}

BOOST_AUTO_TEST_CASE(GenerateNsRrset)
{
  Name label("/nstest");
  name::Component type = label::NS_RR_TYPE;
  uint64_t version = 1234;
  time::seconds ttl(2000);
  Zone zone(m_zoneName);
  m_session.find(zone);

  RrsetFactory rf(TEST_DATABASE2, m_zoneName, m_keyChain, m_certName);

  // rf without checkZoneKey: throw.
  ndn::DelegationList delegations;
  BOOST_CHECK_THROW(rf.generateNsRrset(label, version, ttl, delegations),
                    ndns::RrsetFactory::Error);
  rf.checkZoneKey();

  for (int i = 1; i <= 4; i++) {
    Name name("/delegation/" + std::to_string(i));
    delegations.insert(i, name);
  }

  Rrset rrset = rf.generateNsRrset(label, version, ttl, delegations);

  BOOST_CHECK_EQUAL(rrset.getId(), 0);
  BOOST_REQUIRE(rrset.getZone() != nullptr);
  BOOST_CHECK_EQUAL(*rrset.getZone(), zone);
  BOOST_CHECK_EQUAL(rrset.getLabel(), label);
  BOOST_CHECK_EQUAL(rrset.getType(), type);
  BOOST_CHECK_EQUAL(rrset.getVersion().toVersion(), version);
  BOOST_CHECK_EQUAL(rrset.getTtl(), ttl);

  const Name linkName("/rrest/factory/NDNS/nstest/NS/%FD%04%D2");
  Link link;
  BOOST_CHECK_NO_THROW(link.wireDecode(rrset.getData()));

  BOOST_CHECK_EQUAL(link.getName(), linkName);
  BOOST_CHECK_EQUAL(link.getContentType(), NDNS_LINK);
  BOOST_CHECK(link.getDelegationList() == delegations);

  // BOOST_CHECK_EQUAL(Validator::verifySignature(link, m_cert.getPublicKeyInfo()), true);
  security::verifySignature(link, m_cert);
}

BOOST_AUTO_TEST_CASE(GenerateTxtRrset)
{
  Name label("/txttest");
  name::Component type = label::TXT_RR_TYPE;
  uint64_t version = 1234;
  time::seconds ttl(2000);
  std::vector<std::string> txts;
  Zone zone(m_zoneName);
  m_session.find(zone);

  RrsetFactory rf(TEST_DATABASE2, m_zoneName, m_keyChain, m_certName);

  // rf without checkZoneKey: throw.
  BOOST_CHECK_THROW(rf.generateTxtRrset(label, version, ttl, txts),
                    ndns::RrsetFactory::Error);
  rf.checkZoneKey();
  BOOST_CHECK_NO_THROW(rf.generateTxtRrset(label, version, ttl, txts));
  rf.checkZoneKey();

  for (int i = 1; i <= 4; i++) {
    txts.push_back(std::to_string(i));
  }

  Rrset rrset = rf.generateTxtRrset(label, version, ttl, txts);

  BOOST_CHECK_EQUAL(rrset.getId(), 0);
  BOOST_CHECK_EQUAL(*rrset.getZone(), zone);
  BOOST_CHECK_EQUAL(rrset.getLabel(), label);
  BOOST_CHECK_EQUAL(rrset.getType(), type);
  BOOST_CHECK_EQUAL(rrset.getVersion().toVersion(), version);
  BOOST_CHECK_EQUAL(rrset.getTtl(), ttl);

  Name dataName = m_zoneName.append(label::NDNS_ITERATIVE_QUERY)
                            .append(label)
                            .append(type)
                            .append(rrset.getVersion());

  Data data;
  BOOST_CHECK_NO_THROW(data.wireDecode(rrset.getData()));

  BOOST_CHECK_EQUAL(data.getName(), dataName);
  BOOST_CHECK_EQUAL(data.getContentType(), NDNS_RESP);

  BOOST_CHECK(txts == RrsetFactory::wireDecodeTxt(data.getContent()));

  // shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(m_certName);
  // BOOST_CHECK(Validator::verifySignature(data, cert->getPublicKeyInfo()));
  security::verifySignature(data, m_cert);
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace tests
} // namespace ndns
} // namespace ndn
