// 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(OkStatus(), 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(OkStatus(), 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(OkStatus(), checksum.Verify({}));
}

TEST(IgnoreChecksum, NeverUpdate_VerifyWithData) {
  IgnoreChecksum checksum;

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

TEST(IgnoreChecksum, AfterUpdate_Verify) {
  IgnoreChecksum checksum;

  checksum.Update(std::as_bytes(std::span(kString)));
  EXPECT_EQ(OkStatus(), 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(OkStatus(), checksum.Verify(kBytes));
}

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