/* -*- 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/util/io.hpp"

#include "tests/boost-test.hpp"
#include "tests/key-chain-fixture.hpp"

#include <boost/filesystem.hpp>
#include <boost/mpl/vector.hpp>

namespace ndn::tests {

BOOST_AUTO_TEST_SUITE(Util)
BOOST_AUTO_TEST_SUITE(TestIo)

struct NoEncoding
{
  const io::IoEncoding encoding{io::NO_ENCODING};
  const std::vector<uint8_t> blob{0xd1, 0x0, 0xb0, 0x1a};
  std::istringstream stream{std::string("\xd1\x00\xb0\x1a", 4), std::ios_base::binary};
};

struct Base64Encoding
{
  const io::IoEncoding encoding = io::BASE64;
  const std::vector<uint8_t> blob{0x42, 0x61, 0x73, 0x65, 0x36, 0x34, 0x45, 0x6e, 0x63};
  std::istringstream stream{"QmFzZTY0RW5j\n", std::ios_base::binary};
};

struct HexEncoding
{
  const io::IoEncoding encoding = io::HEX;
  const std::vector<uint8_t> blob{0x48, 0x65, 0x78, 0x45, 0x6e, 0x63};
  std::istringstream stream{"486578456E63", std::ios_base::binary};
};

using Encodings = boost::mpl::vector<NoEncoding, Base64Encoding, HexEncoding>;

BOOST_AUTO_TEST_CASE_TEMPLATE(LoadBuffer, T, Encodings)
{
  T t;
  shared_ptr<Buffer> buf = io::loadBuffer(t.stream, t.encoding);
  BOOST_CHECK_EQUAL_COLLECTIONS(buf->begin(), buf->end(), t.blob.begin(), t.blob.end());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(SaveBuffer, T, Encodings)
{
  T t;
  std::ostringstream os(std::ios_base::binary);
  io::saveBuffer(t.blob, os, t.encoding);
  BOOST_CHECK_EQUAL(os.str(), t.stream.str());
}

BOOST_AUTO_TEST_CASE(LoadBufferException)
{
  std::ifstream in("this-file-does-not-exist", std::ios_base::binary);
  BOOST_CHECK_THROW(io::loadBuffer(in, io::NO_ENCODING), io::Error);
}

BOOST_AUTO_TEST_CASE(SaveBufferException)
{
  class NullStreambuf : public std::streambuf
  {
  };

  NullStreambuf nullbuf;
  std::ostream out(&nullbuf);
  const Buffer buffer(1);
  BOOST_CHECK_THROW(io::saveBuffer(buffer, out, io::NO_ENCODING), io::Error);
}

BOOST_AUTO_TEST_CASE(UnknownIoEncoding)
{
  std::stringstream ss;
  BOOST_CHECK_THROW(io::loadTlv<Name>(ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
  BOOST_CHECK_THROW(io::loadBuffer(ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
  BOOST_CHECK_THROW(io::saveBuffer({}, ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
}

class FileIoFixture
{
protected:
  FileIoFixture()
    : filepath(boost::filesystem::path(UNIT_TESTS_TMPDIR) / "TestIo")
    , filename(filepath.string())
  {
    boost::filesystem::create_directories(filepath.parent_path());
  }

  ~FileIoFixture()
  {
    boost::system::error_code ec;
    boost::filesystem::remove(filepath, ec); // ignore error
  }

  /**
   * \brief Create a directory at `filepath`, so that it's neither readable nor writable as a file.
   */
  void
  mkdir() const
  {
    boost::filesystem::create_directory(filepath);
  }

  template<typename Container>
  Container
  readFile() const
  {
    Container container;
    std::ifstream fs(filename, std::ios_base::binary);
    BOOST_REQUIRE_MESSAGE(fs, "error opening file");
    char ch;
    while (fs.get(ch)) {
      container.push_back(static_cast<typename Container::value_type>(ch));
    }
    return container;
  }

  template<typename Container>
  void
  writeFile(const Container& content) const
  {
    std::ofstream fs(filename, std::ios_base::binary);
    BOOST_REQUIRE_MESSAGE(fs, "error opening file");
    for (auto ch : content) {
      fs.put(static_cast<char>(ch));
    }
    BOOST_REQUIRE_MESSAGE(fs, "error writing file");
  }

protected:
  const boost::filesystem::path filepath;
  const std::string filename;
};

BOOST_FIXTURE_TEST_SUITE(FileIo, FileIoFixture)

class EncodableType
{
public:
  Block
  wireEncode() const
  {
    if (shouldThrow) {
      NDN_THROW(tlv::Error("encode error"));
    }

    // block will be 0xAA, 0x01, 0xDD
    return makeNonNegativeIntegerBlock(0xAA, 0xDD);
  }

public:
  bool shouldThrow = false;
};

class DecodableType
{
public:
  DecodableType() = default;

  explicit
  DecodableType(const Block& block)
  {
    wireDecode(block);
  }

  void
  wireDecode(const Block& block)
  {
    BOOST_TEST(block == "BB01EE"_block);
  }
};

class DecodableTypeThrow
{
public:
  DecodableTypeThrow() = default;

  explicit
  DecodableTypeThrow(const Block& block)
  {
    wireDecode(block);
  }

  void
  wireDecode(const Block&)
  {
    NDN_THROW(tlv::Error("decode error"));
  }
};

BOOST_AUTO_TEST_CASE(LoadNoEncoding)
{
  this->writeFile<std::vector<uint8_t>>({0xBB, 0x01, 0xEE});
  shared_ptr<DecodableType> decoded = io::load<DecodableType>(filename, io::NO_ENCODING);
  BOOST_CHECK(decoded != nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_NO_THROW(io::loadTlv<DecodableType>(ifs, io::NO_ENCODING));
}

BOOST_AUTO_TEST_CASE(LoadBase64)
{
  this->writeFile<std::string>("uwHu\n"); // printf '\xBB\x01\xEE' | base64
  shared_ptr<DecodableType> decoded = io::load<DecodableType>(filename, io::BASE64);
  BOOST_CHECK(decoded != nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_NO_THROW(io::loadTlv<DecodableType>(ifs, io::BASE64));
}

BOOST_AUTO_TEST_CASE(LoadBase64Newline64)
{
  this->writeFile<std::string>(
    "CEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
    "AAAAAAAAAAAA\n");
  // printf '\x08\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
  //         \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
  //         \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
  //         \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | base64
  shared_ptr<name::Component> decoded = io::load<name::Component>(filename, io::BASE64);
  BOOST_CHECK(decoded != nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_NO_THROW(io::loadTlv<name::Component>(ifs, io::BASE64));
}

BOOST_AUTO_TEST_CASE(LoadBase64Newline32)
{
  this->writeFile<std::string>(
    "CEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
    "AAAAAAAAAAAA\n");
  shared_ptr<name::Component> decoded = io::load<name::Component>(filename, io::BASE64);
  BOOST_CHECK(decoded != nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_NO_THROW(io::loadTlv<name::Component>(ifs, io::BASE64));
}

BOOST_AUTO_TEST_CASE(LoadBase64NewlineEnd)
{
  this->writeFile<std::string>(
    "CEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
  shared_ptr<name::Component> decoded = io::load<name::Component>(filename, io::BASE64);
  BOOST_CHECK(decoded != nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_NO_THROW(io::loadTlv<name::Component>(ifs, io::BASE64));
}

BOOST_AUTO_TEST_CASE(LoadBase64NoNewline)
{
  this->writeFile<std::string>(
    "CEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  shared_ptr<name::Component> decoded = io::load<name::Component>(filename, io::BASE64);
  BOOST_CHECK(decoded != nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_NO_THROW(io::loadTlv<name::Component>(ifs, io::BASE64));
}

BOOST_AUTO_TEST_CASE(LoadHex)
{
  this->writeFile<std::string>("BB01EE");
  shared_ptr<DecodableType> decoded = io::load<DecodableType>(filename, io::HEX);
  BOOST_CHECK(decoded != nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_NO_THROW(io::loadTlv<DecodableType>(ifs, io::HEX));
}

BOOST_AUTO_TEST_CASE(LoadDecodeException)
{
  this->writeFile<std::vector<uint8_t>>({0xBB, 0x01, 0xEE});
  shared_ptr<DecodableTypeThrow> decoded;
  BOOST_CHECK_NO_THROW(decoded = io::load<DecodableTypeThrow>(filename, io::NO_ENCODING));
  BOOST_CHECK(decoded == nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_THROW(io::loadTlv<DecodableTypeThrow>(ifs, io::NO_ENCODING), io::Error);
}

BOOST_AUTO_TEST_CASE(LoadNotHex)
{
  this->writeFile<std::string>("not-hex");
  shared_ptr<DecodableType> decoded;
  BOOST_CHECK_NO_THROW(decoded = io::load<DecodableType>(filename, io::HEX));
  BOOST_CHECK(decoded == nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_THROW(io::loadTlv<DecodableType>(ifs, io::HEX), io::Error);
}

BOOST_AUTO_TEST_CASE(LoadEmpty)
{
  this->writeFile<std::vector<uint8_t>>({});
  shared_ptr<DecodableType> decoded;
  BOOST_CHECK_NO_THROW(decoded = io::load<DecodableType>(filename, io::NO_ENCODING));
  BOOST_CHECK(decoded == nullptr);

  std::ifstream ifs(filename);
  BOOST_CHECK_THROW(io::loadTlv<DecodableType>(ifs, io::NO_ENCODING), io::Error);
}

BOOST_AUTO_TEST_CASE(LoadFileNotReadable)
{
  shared_ptr<DecodableType> decoded;
  BOOST_CHECK_NO_THROW(decoded = io::load<DecodableType>(filename, io::NO_ENCODING));
  BOOST_CHECK(decoded == nullptr);
}

BOOST_AUTO_TEST_CASE(SaveNoEncoding)
{
  EncodableType encoded;
  BOOST_CHECK_NO_THROW(io::save(encoded, filename, io::NO_ENCODING));
  auto content = this->readFile<std::vector<uint8_t>>();
  uint8_t expected[] = {0xAA, 0x01, 0xDD};
  BOOST_CHECK_EQUAL_COLLECTIONS(content.begin(), content.end(),
                                expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(SaveBase64)
{
  EncodableType encoded;
  BOOST_CHECK_NO_THROW(io::save(encoded, filename, io::BASE64));
  auto content = this->readFile<std::string>();
  BOOST_CHECK_EQUAL(content, "qgHd\n"); // printf '\xAA\x01\xDD' | base64
}

BOOST_AUTO_TEST_CASE(SaveHex)
{
  EncodableType encoded;
  BOOST_CHECK_NO_THROW(io::save(encoded, filename, io::HEX));
  auto content = this->readFile<std::string>();
  BOOST_CHECK_EQUAL(content, "AA01DD");
}

BOOST_AUTO_TEST_CASE(SaveException)
{
  EncodableType encoded;
  encoded.shouldThrow = true;
  BOOST_CHECK_THROW(io::save(encoded, filename, io::NO_ENCODING), io::Error);
}

BOOST_AUTO_TEST_CASE(SaveFileNotWritable)
{
  this->mkdir();
  EncodableType encoded;
  encoded.shouldThrow = true;
  BOOST_CHECK_THROW(io::save(encoded, filename, io::NO_ENCODING), io::Error);
}

BOOST_AUTO_TEST_SUITE_END() // FileIo

class IdCertFixture : public FileIoFixture
                    , public KeyChainFixture
{
};

BOOST_FIXTURE_TEST_CASE(IdCert, IdCertFixture)
{
  auto identity = m_keyChain.createIdentity("/TestIo/IdCert", RsaKeyParams());
  auto key = identity.getDefaultKey();
  const auto& cert = key.getDefaultCertificate();
  io::save(cert, filename);

  auto readCert = io::load<security::Certificate>(filename);

  BOOST_REQUIRE(readCert != nullptr);
  BOOST_CHECK_EQUAL(cert.getName(), readCert->getName());

  this->writeFile<std::string>("");
  readCert = io::load<security::Certificate>(filename);
  BOOST_REQUIRE(readCert == nullptr);
}

BOOST_AUTO_TEST_SUITE_END() // TestIo
BOOST_AUTO_TEST_SUITE_END() // Util

} // namespace ndn::tests
