/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2022 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/sha256.hpp"
#include "ndn-cxx/util/string-helper.hpp"

#include "tests/boost-test.hpp"

#include <boost/endian/conversion.hpp>
#include <sstream>

namespace ndn {
namespace util {
namespace tests {

BOOST_AUTO_TEST_SUITE(Util)
BOOST_AUTO_TEST_SUITE(TestSha256)

BOOST_AUTO_TEST_CASE(Basic)
{
  const uint8_t buf[] = {0x01, 0x02, 0x03, 0x04};
  auto input = make_span(buf);
  auto expected = fromHex("9f64a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a");

  Sha256 statefulSha256;
  BOOST_CHECK_EQUAL(statefulSha256.empty(), true);

  statefulSha256.update(input.subspan(0, 1));
  statefulSha256.update(input.subspan(1, 1));
  statefulSha256.update(input.subspan(2, 1));
  statefulSha256.update(input.subspan(3, 1));
  ConstBufferPtr digest = statefulSha256.computeDigest();
  BOOST_CHECK_EQUAL(digest->size(), Sha256::DIGEST_SIZE);
  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
}

BOOST_AUTO_TEST_CASE(ConstructFromStream)
{
  const std::string input = "Hello, world!";
  auto expected = fromHex("315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3");

  std::istringstream is(input);
  Sha256 sha(is);
  BOOST_CHECK_EQUAL(sha.empty(), false);
  BOOST_CHECK_EQUAL(sha.toString(), "315F5BDB76D078C43B8AC0064E4A0164612B1FCE77C869345BFC94C75894EDD3");

  ConstBufferPtr digest = sha.computeDigest();
  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
}

BOOST_AUTO_TEST_CASE(Compare)
{
  const uint8_t origin[] = {0x01, 0x02, 0x03, 0x04};

  Sha256 digest1;
  digest1.update(origin);
  digest1.computeDigest();

  Sha256 digest2;
  auto in = make_span(origin);
  digest2.update(in.first(2));
  digest2.update(in.last(2));
  digest2.computeDigest();

  BOOST_CHECK_EQUAL(digest1 == digest2, true);
  BOOST_CHECK_EQUAL(digest1 != digest2, false);
}

BOOST_AUTO_TEST_CASE(InsertionOperatorSha256)
{
  auto expected = fromHex("d7bd34bfe44a18d2aa755a344fe3e6b06ed0473772e6dfce16ac71ba0b0a241c");

  Sha256 innerDigest;
  innerDigest << "TEST";

  Sha256 statefulSha256;
  statefulSha256 << innerDigest;
  ConstBufferPtr digest = statefulSha256.computeDigest();

  BOOST_CHECK_EQUAL(statefulSha256.empty(), false);
  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
}

BOOST_AUTO_TEST_CASE(InsertionOperatorString)
{
  const std::string input = "Hello, world!";
  auto expected = fromHex("315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3");

  Sha256 statefulSha256;
  statefulSha256 << input;
  ConstBufferPtr digest = statefulSha256.computeDigest();

  BOOST_CHECK_EQUAL(statefulSha256.empty(), false);
  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
}

BOOST_AUTO_TEST_CASE(InsertionOperatorBlock)
{
  const uint8_t input[] = {
    0x16, 0x1b, // SignatureInfo
      0x1b, 0x01, // SignatureType
        0x01, // Sha256WithRsa
      0x1c, 0x16, // KeyLocator
        0x07, 0x14, // Name
          0x08, 0x04,
            0x74, 0x65, 0x73, 0x74,
          0x08, 0x03,
            0x6b, 0x65, 0x79,
          0x08, 0x07,
            0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
  };
  auto expected = fromHex("b372edfd4d6a4db2cfeaeead6c34fdee9b9e759f7b8d799cf8067e39e7f2886c");

  Sha256 statefulSha256;
  statefulSha256 << Block{input};
  ConstBufferPtr digest = statefulSha256.computeDigest();

  BOOST_CHECK_EQUAL(statefulSha256.empty(), false);
  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
}

BOOST_AUTO_TEST_CASE(InsertionOperatorUint64t)
{
  const uint64_t input[] = {1, 2, 3, 4};
  auto expected = fromHex("7236c00c170036c6de133a878210ddd58567aa1d0619a0f70f69e38ae6f916e9");

  Sha256 statefulSha256;
  for (size_t i = 0; i < sizeof(input) / sizeof(uint64_t); ++i) {
    statefulSha256 << boost::endian::native_to_big(input[i]);
  }
  ConstBufferPtr digest = statefulSha256.computeDigest();

  BOOST_CHECK_EQUAL(statefulSha256.empty(), false);
  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
}

BOOST_AUTO_TEST_CASE(Reset)
{
  Sha256 sha;
  BOOST_CHECK_EQUAL(sha.empty(), true);

  sha << 42;
  BOOST_CHECK_EQUAL(sha.empty(), false);

  sha.computeDigest(); // finalize
  sha.reset();
  BOOST_CHECK_EQUAL(sha.empty(), true);
  BOOST_CHECK_NO_THROW(sha << 42);
}

BOOST_AUTO_TEST_CASE(Error)
{
  Sha256 sha;
  sha << 42;
  sha.computeDigest(); // finalize
  BOOST_CHECK_THROW(sha << 42, Sha256::Error);
}

BOOST_AUTO_TEST_CASE(StaticComputeDigest)
{
  auto expected = fromHex("9f64a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a");

  ConstBufferPtr digest = Sha256::computeDigest({0x01, 0x02, 0x03, 0x04});
  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
}

BOOST_AUTO_TEST_CASE(Print)
{
  const uint8_t origin[] = {0x94, 0xEE, 0x05, 0x93, 0x35, 0xE5, 0x87, 0xE5,
                            0x01, 0xCC, 0x4B, 0xF9, 0x06, 0x13, 0xE0, 0x81,
                            0x4F, 0x00, 0xA7, 0xB0, 0x8B, 0xC7, 0xC6, 0x48,
                            0xFD, 0x86, 0x5A, 0x2A, 0xF6, 0xA2, 0x2C, 0xC2};
  const auto expected = toHex(origin);

  Sha256 digest;
  digest << "TEST";
  std::ostringstream os;
  os << digest;
  BOOST_CHECK_EQUAL(os.str(), expected);
  BOOST_CHECK_EQUAL(digest.toString(), expected);
}

BOOST_AUTO_TEST_SUITE_END() // TestSha256
BOOST_AUTO_TEST_SUITE_END() // Util

} // namespace tests
} // namespace util
} // namespace ndn
