/* -*- 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.
 */

#ifndef NDN_TESTS_KEY_CHAIN_FIXTURE_HPP
#define NDN_TESTS_KEY_CHAIN_FIXTURE_HPP

#include "security/v2/key-chain.hpp"

#include "boost-test.hpp"
#include "identity-management-fixture.hpp"

#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <fstream>

namespace ndn {
namespace tests {

/**
 * @brief Fixture to adjust/restore NDN_CLIENT_PIB and NDN_CLIENT_TPM paths
 *
 * Note that the specified PATH will be removed after fixture is destroyed.
 * **Do not specify non-temporary paths.**
 */
template<class Path>
class PibDirFixture
{
public:
  PibDirFixture()
    : m_pibDir(Path().PATH)
  {
    if (getenv("NDN_CLIENT_PIB") != nullptr) {
      m_oldPib = getenv("NDN_CLIENT_PIB");
    }
    if (getenv("NDN_CLIENT_TPM") != nullptr) {
      m_oldTpm = getenv("NDN_CLIENT_TPM");
    }

    /// @todo Consider change to an in-memory PIB/TPM
    setenv("NDN_CLIENT_PIB", ("pib-sqlite3:" + m_pibDir).c_str(), true);
    setenv("NDN_CLIENT_TPM", ("tpm-file:" + m_pibDir).c_str(), true);
  }

  ~PibDirFixture()
  {
    if (!m_oldPib.empty()) {
      setenv("NDN_CLIENT_PIB", m_oldPib.c_str(), true);
    }
    else {
      unsetenv("NDN_CLIENT_PIB");
    }

    if (!m_oldTpm.empty()) {
      setenv("NDN_CLIENT_TPM", m_oldTpm.c_str(), true);
    }
    else {
      unsetenv("NDN_CLIENT_TPM");
    }

    boost::filesystem::remove_all(m_pibDir);
    const_cast<std::string&>(security::v2::KeyChain::getDefaultPibLocator()).clear();
    const_cast<std::string&>(security::v2::KeyChain::getDefaultTpmLocator()).clear();
  }

protected:
  const std::string m_pibDir;

private:
  std::string m_oldPib;
  std::string m_oldTpm;
};

/**
 * @brief Extension of PibDirFixture to set TEST_HOME variable and allow config file creation
 */
template<class Path>
class TestHomeFixture : public PibDirFixture<Path>
{
public:
  TestHomeFixture()
  {
    setenv("TEST_HOME", this->m_pibDir.c_str(), true);
  }

  ~TestHomeFixture()
  {
    unsetenv("TEST_HOME");
  }

  void
  createClientConf(std::initializer_list<std::string> lines)
  {
    boost::filesystem::create_directories(boost::filesystem::path(this->m_pibDir) / ".ndn");
    std::ofstream of((boost::filesystem::path(this->m_pibDir) / ".ndn" / "client.conf").c_str());
    for (auto line : lines) {
      boost::replace_all(line, "%PATH%", this->m_pibDir);
      of << line << std::endl;
    }
  }
};


struct DefaultPibDir
{
  const std::string PATH = "build/keys";
};

/**
 * @brief Fixture to create a test KeyChain with default identity
 */
class KeyChainFixture : public PibDirFixture<DefaultPibDir>,
                        public IdentityManagementFixture
{
public:
  KeyChainFixture();
};


} // namespace tests
} // namespace ndn

#endif // NDN_TESTS_KEY_CHAIN_FIXTURE_HPP
