// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "pw_kvs/checksum.h"

#include "gtest/gtest.h"
#include "pw_kvs/crc16_checksum.h"

namespace pw::kvs {
namespace {

using std::byte;

constexpr std::string_view kString =
    "In the beginning the Universe was created. This has made a lot of "
    "people very angry and been widely regarded as a bad move.";
constexpr uint16_t kStringCrc = 0xC184;

TEST(Checksum, UpdateAndVerify) {
  ChecksumCrc16 crc16_algo;
  ChecksumAlgorithm& algo = crc16_algo;

  algo.Update(kString.data(), kString.size());
  EXPECT_EQ(Status::Ok(),
            algo.Verify(std::as_bytes(std::span(&kStringCrc, 1))));
}

TEST(Checksum, Verify_Failure) {
  ChecksumCrc16 algo;
  EXPECT_EQ(Status::DataLoss(),
            algo.Verify(std::as_bytes(std::span(kString.data(), 2))));
}

TEST(Checksum, Verify_InvalidSize) {
  ChecksumCrc16 algo;
  EXPECT_EQ(Status::InvalidArgument(), algo.Verify({}));
  EXPECT_EQ(Status::InvalidArgument(),
            algo.Verify(std::as_bytes(std::span(kString.substr(0, 1)))));
}

TEST(Checksum, Verify_LargerState_ComparesToTruncatedData) {
  byte crc[3] = {byte{0x84}, byte{0xC1}, byte{0x33}};
  ChecksumCrc16 algo;
  ASSERT_GT(sizeof(crc), algo.size_bytes());

  algo.Update(std::as_bytes(std::span(kString)));

  EXPECT_EQ(Status::Ok(), algo.Verify(crc));
}

TEST(Checksum, Reset) {
  ChecksumCrc16 crc_algo;
  crc_algo.Update(std::as_bytes(std::span(kString)));
  crc_algo.Reset();

  std::span state = crc_algo.Finish();
  EXPECT_EQ(state[0], byte{0xFF});
  EXPECT_EQ(state[1], byte{0xFF});
}

TEST(IgnoreChecksum, NeverUpdate_VerifyWithoutData) {
  IgnoreChecksum checksum;

  EXPECT_EQ(Status::Ok(), checksum.Verify({}));
}

TEST(IgnoreChecksum, NeverUpdate_VerifyWithData) {
  IgnoreChecksum checksum;

  EXPECT_EQ(Status::Ok(), checksum.Verify(std::as_bytes(std::span(kString))));
}

TEST(IgnoreChecksum, AfterUpdate_Verify) {
  IgnoreChecksum checksum;

  checksum.Update(std::as_bytes(std::span(kString)));
  EXPECT_EQ(Status::Ok(), checksum.Verify({}));
}

constexpr size_t kAlignment = 10;

constexpr std::string_view kData =
    "123456789_123456789_123456789_123456789_123456789_"   //  50
    "123456789_123456789_123456789_123456789_123456789_";  // 100
const std::span<const byte> kBytes = std::as_bytes(std::span(kData));

class PickyChecksum final : public AlignedChecksum<kAlignment, 32> {
 public:
  PickyChecksum() : AlignedChecksum(data_), data_{}, size_(0) {}

  void Reset() override {}

  void FinalizeAligned() override { EXPECT_EQ(kData.size(), size_); }

  void UpdateAligned(std::span<const std::byte> data) override {
    ASSERT_EQ(data.size() % kAlignment, 0u);
    EXPECT_EQ(kData.substr(0, data.size()),
              std::string_view(reinterpret_cast<const char*>(data.data()),
                               data.size()));

    std::memcpy(&data_[size_], data.data(), data.size());
    size_ += data.size();
  }

 private:
  std::byte data_[kData.size()];
  size_t size_;
};

TEST(AlignedChecksum, MaintainsAlignment) {
  PickyChecksum checksum;

  // Write values smaller than the alignment.
  checksum.Update(kBytes.subspan(0, 1));
  checksum.Update(kBytes.subspan(1, 9));

  // Write values larger than the alignment but smaller than the buffer.
  checksum.Update(kBytes.subspan(10, 11));

  // Exactly fill the remainder of the buffer.
  checksum.Update(kBytes.subspan(21, 11));

  // Fill the buffer more than once.
  checksum.Update(kBytes.subspan(32, 66));

  // Write nothing.
  checksum.Update(kBytes.subspan(98, 0));

  // Write the remaining data.
  checksum.Update(kBytes.subspan(98, 2));

  auto state = checksum.Finish();
  EXPECT_EQ(std::string_view(reinterpret_cast<const char*>(state.data()),
                             state.size()),
            kData);
  EXPECT_EQ(Status::Ok(), checksum.Verify(kBytes));
}

}  // namespace
}  // namespace pw::kvs
