/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017 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/v1/sec-public-info-sqlite3.hpp"
#include "security/v1/key-chain.hpp"
#include "security/v1/cryptopp.hpp"
#include "encoding/buffer-stream.hpp"
#include "util/time.hpp"

#include "boost-test.hpp"

#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>

namespace ndn {
namespace security {
namespace v1 {
namespace tests {

class PibTmpPathFixture
{
public:
  PibTmpPathFixture()
  {
    boost::system::error_code error;
    tmpPath = boost::filesystem::temp_directory_path(error);
    BOOST_REQUIRE(boost::system::errc::success == error.value());
    tmpPath /= boost::lexical_cast<std::string>(random::generateWord32());
  }

  ~PibTmpPathFixture()
  {
    boost::filesystem::remove_all(tmpPath);
  }

public:
  boost::filesystem::path tmpPath;
};

BOOST_AUTO_TEST_SUITE(Security)
BOOST_AUTO_TEST_SUITE(V1)
BOOST_AUTO_TEST_SUITE(TestSecPublicInfoSqlite3)

const std::string RSA_DER("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuFoDcNtffwbfFix64fw0\
hI2tKMkFrc6Ex7yw0YLMK9vGE8lXOyBl/qXabow6RCz+GldmFN6E2Qhm1+AX3Zm5\
sj3H53/HPtzMefvMQ9X7U+lK8eNMWawpRzvBh4/36VrK/awlkNIVIQ9aXj6q6BVe\
zL+zWT/WYemLq/8A1/hHWiwCtfOH1xQhGqWHJzeSgwIgOOrzxTbRaCjhAb1u2TeV\
yx/I9H/DV+AqSHCaYbB92HDcDN0kqwSnUf5H1+osE9MR5DLBLhXdSiULSgxT3Or/\
y2QgsgUK59WrjhlVMPEiHHRs15NZJbL1uQFXjgScdEarohcY3dilqotineFZCeN8\
DwIDAQAB");
const std::string ECDSA_DER("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENZpqkPJDj8uhSpffOiCbvSYMLsGB\
1Eo/WU6mrexjGvduQXjqwon/eSHFI6EgHZk8L9KfiV5XVtVsk2g5wIpJVg==");

BOOST_FIXTURE_TEST_CASE(Basic, PibTmpPathFixture)
{
  SecPublicInfoSqlite3 pib(tmpPath.generic_string());

  BOOST_CHECK(pib.doesTableExist("Identity"));
  BOOST_CHECK(pib.doesTableExist("Key"));
  BOOST_CHECK(pib.doesTableExist("Certificate"));
}

BOOST_FIXTURE_TEST_CASE(TpmLocatorTest, PibTmpPathFixture)
{
  SecPublicInfoSqlite3 pib(tmpPath.generic_string());

  BOOST_REQUIRE_THROW(pib.getTpmLocator(), SecPublicInfo::Error);
  pib.addIdentity("/test/id1");
  BOOST_CHECK(pib.doesIdentityExist("/test/id1"));

  // Pib does not have tpmInfo set yet, setTpmInfo simply set the tpmInfo.
  std::string tpmLocator("tpm-file:");
  tpmLocator.append((tmpPath / "tpm").generic_string());
  pib.setTpmLocator(tpmLocator);
  BOOST_CHECK(pib.doesIdentityExist("/test/id1"));

  BOOST_REQUIRE_NO_THROW(pib.getTpmLocator());
  BOOST_CHECK_EQUAL(tpmLocator, pib.getTpmLocator());

  // Pib has tpmInfo set, set a different tpmInfo will reset Pib content.
  std::string tpmLocator3("tpm-osxkeychain:");
  pib.setTpmLocator(tpmLocator3);
  BOOST_CHECK(!pib.doesIdentityExist("/test/id1"));
}

BOOST_AUTO_TEST_CASE(KeyTypeRsa)
{
  using namespace CryptoPP;

  OBufferStream os;
  StringSource ss(reinterpret_cast<const uint8_t*>(RSA_DER.c_str()), RSA_DER.size(),
                  true, new Base64Decoder(new FileSink(os)));

  shared_ptr<v1::PublicKey> rsaKey;
  BOOST_REQUIRE_NO_THROW(rsaKey = make_shared<v1::PublicKey>(os.buf()->buf(), os.buf()->size()));
  Name rsaKeyName("/TestSecPublicInfoSqlite3/KeyType/RSA/ksk-123");
  SecPublicInfoSqlite3 pib;
  pib.addKey(rsaKeyName, *rsaKey);

  BOOST_CHECK_EQUAL(KeyType::RSA, pib.getPublicKeyType(rsaKeyName));

  pib.deleteIdentityInfo(Name("/TestSecPublicInfoSqlite3/KeyType/RSA"));
}

BOOST_AUTO_TEST_CASE(KeyTypeEcdsa)
{
  using namespace CryptoPP;

  OBufferStream os;
  StringSource ss(reinterpret_cast<const uint8_t*>(ECDSA_DER.c_str()), ECDSA_DER.size(),
                  true, new Base64Decoder(new FileSink(os)));

  shared_ptr<v1::PublicKey> ecdsaKey;
  BOOST_REQUIRE_NO_THROW(ecdsaKey = make_shared<v1::PublicKey>(os.buf()->buf(), os.buf()->size()));
  Name ecdsaKeyName("/TestSecPublicInfoSqlite3/KeyType/ECDSA/ksk-123");
  SecPublicInfoSqlite3 pib;
  pib.addKey(ecdsaKeyName, *ecdsaKey);

  BOOST_CHECK_EQUAL(KeyType::EC, pib.getPublicKeyType(ecdsaKeyName));
  pib.deleteIdentityInfo(Name("/TestSecPublicInfoSqlite3/KeyType/ECDSA"));
}

BOOST_AUTO_TEST_CASE(KeyTypeNonExistent)
{
  Name nullKeyName("/TestSecPublicInfoSqlite3/KeyType/Null");
  SecPublicInfoSqlite3 pib;

  BOOST_CHECK_EQUAL(KeyType::NONE, pib.getPublicKeyType(nullKeyName));
}

BOOST_AUTO_TEST_SUITE_END() // TestSecPublicInfoSqlite3
BOOST_AUTO_TEST_SUITE_END() // V1
BOOST_AUTO_TEST_SUITE_END() // Security

} // namespace tests
} // namespace v1
} // namespace security
} // namespace ndn
