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

#define DUMP_KVS_STATE_TO_FILE 0
#define USE_MEMORY_BUFFER 1
#define PW_LOG_USE_ULTRA_SHORT_NAMES 1

#include "pw_kvs/key_value_store.h"

#include <array>
#include <cstdio>
#include <cstring>

#if DUMP_KVS_STATE_TO_FILE
#include <vector>
#endif  // DUMP_KVS_STATE_TO_FILE

#include "gtest/gtest.h"
#include "pw_checksum/ccitt_crc16.h"
#include "pw_kvs/crc16_checksum.h"
#include "pw_kvs/flash_memory.h"
#include "pw_kvs_private/byte_utils.h"
#include "pw_kvs_private/entry.h"
#include "pw_kvs_private/macros.h"
#include "pw_log/log.h"
#include "pw_span/span.h"
#include "pw_status/status.h"
#include "pw_string/string_builder.h"

#if USE_MEMORY_BUFFER
#include "pw_kvs/in_memory_fake_flash.h"
#endif  // USE_MEMORY_BUFFER

namespace pw::kvs {
namespace {

using internal::EntryHeader;
using std::byte;

constexpr size_t kMaxEntries = 256;
constexpr size_t kMaxUsableSectors = 256;

// Test the functions in byte_utils.h. Create a byte array with AsBytes and
// ByteStr and check that its contents are correct.
constexpr std::array<char, 2> kTestArray = {'a', 'b'};

constexpr auto kAsBytesTest = AsBytes(
    'a', uint16_t(1), uint8_t(23), kTestArray, ByteStr("c"), uint64_t(-1));

static_assert(kAsBytesTest.size() == 15);
static_assert(kAsBytesTest[0] == std::byte{'a'});
static_assert(kAsBytesTest[1] == std::byte{1});
static_assert(kAsBytesTest[2] == std::byte{0});
static_assert(kAsBytesTest[3] == std::byte{23});
static_assert(kAsBytesTest[4] == std::byte{'a'});
static_assert(kAsBytesTest[5] == std::byte{'b'});
static_assert(kAsBytesTest[6] == std::byte{'c'});
static_assert(kAsBytesTest[7] == std::byte{0xff});
static_assert(kAsBytesTest[8] == std::byte{0xff});
static_assert(kAsBytesTest[9] == std::byte{0xff});
static_assert(kAsBytesTest[10] == std::byte{0xff});
static_assert(kAsBytesTest[11] == std::byte{0xff});
static_assert(kAsBytesTest[12] == std::byte{0xff});
static_assert(kAsBytesTest[13] == std::byte{0xff});
static_assert(kAsBytesTest[14] == std::byte{0xff});

// Test that the ConvertsToSpan trait correctly idenitifies types that convert
// to span.
static_assert(!ConvertsToSpan<int>());
static_assert(!ConvertsToSpan<void>());
static_assert(!ConvertsToSpan<std::byte>());
static_assert(!ConvertsToSpan<std::byte*>());

static_assert(ConvertsToSpan<std::array<int, 5>>());
static_assert(ConvertsToSpan<decltype("Hello!")>());

static_assert(ConvertsToSpan<std::string_view>());
static_assert(ConvertsToSpan<std::string_view&>());
static_assert(ConvertsToSpan<std::string_view&&>());

static_assert(ConvertsToSpan<const std::string_view>());
static_assert(ConvertsToSpan<const std::string_view&>());
static_assert(ConvertsToSpan<const std::string_view&&>());

static_assert(ConvertsToSpan<span<int>>());
static_assert(ConvertsToSpan<span<byte>>());
static_assert(ConvertsToSpan<span<const int*>>());
static_assert(ConvertsToSpan<span<bool>&&>());
static_assert(ConvertsToSpan<const span<bool>&>());
static_assert(ConvertsToSpan<span<bool>&&>());

// This is a self contained flash unit with both memory and a single partition.
template <uint32_t sector_size_bytes, uint16_t sector_count>
struct FlashWithPartitionFake {
  // Default to 16 byte alignment, which is common in practice.
  FlashWithPartitionFake() : FlashWithPartitionFake(16) {}
  FlashWithPartitionFake(size_t alignment_bytes)
      : memory(alignment_bytes), partition(&memory, 0, memory.sector_count()) {}

  FakeFlashBuffer<sector_size_bytes, sector_count> memory;
  FlashPartition partition;

 public:
#if DUMP_KVS_STATE_TO_FILE
  Status Dump(const char* filename) {
    std::FILE* out_file = std::fopen(filename, "w+");
    if (out_file == nullptr) {
      PW_LOG_ERROR("Failed to dump to %s", filename);
      return Status::DATA_LOSS;
    }
    std::vector<std::byte> out_vec(memory.size_bytes());
    Status status =
        memory.Read(0, pw::span<std::byte>(out_vec.data(), out_vec.size()));
    if (status != Status::OK) {
      fclose(out_file);
      return status;
    }

    size_t written =
        std::fwrite(out_vec.data(), 1, memory.size_bytes(), out_file);
    if (written != memory.size_bytes()) {
      PW_LOG_ERROR("Failed to dump to %s, written=%u",
                   filename,
                   static_cast<unsigned>(written));
      status = Status::DATA_LOSS;
    } else {
      PW_LOG_INFO("Dumped to %s", filename);
      status = Status::OK;
    }

    fclose(out_file);
    return status;
  }
#else
  Status Dump(const char*) { return Status::OK; }
#endif  // DUMP_KVS_STATE_TO_FILE
};

typedef FlashWithPartitionFake<4 * 128 /*sector size*/, 6 /*sectors*/> Flash;

#if USE_MEMORY_BUFFER
// Although it might be useful to test other configurations, some tests require
// at least 3 sectors; therfore it should have this when checked in.
FakeFlashBuffer<4 * 1024, 4> test_flash(
    16);  // 4 x 4k sectors, 16 byte alignment
FlashPartition test_partition(&test_flash, 0, test_flash.sector_count());
FakeFlashBuffer<1024, 60> large_test_flash(8);
FlashPartition large_test_partition(&large_test_flash,
                                    0,
                                    large_test_flash.sector_count());
#else   // TODO: Test with real flash
FlashPartition& test_partition = FlashExternalTestPartition();
#endif  // USE_MEMORY_BUFFER

std::array<byte, 512> buffer;
constexpr std::array<const char*, 3> keys{"TestKey1", "Key2", "TestKey3"};

ChecksumCrc16 checksum;
constexpr EntryHeaderFormat format{.magic = 0xBAD'C0D3, .checksum = &checksum};

size_t RoundUpForAlignment(size_t size) {
  return AlignUp(size, test_partition.alignment_bytes());
}

// This class gives attributes of KVS that we are testing against
class KvsAttributes {
 public:
  KvsAttributes(size_t key_size, size_t data_size)
      : chunk_header_size_(RoundUpForAlignment(sizeof(EntryHeader))),
        data_size_(RoundUpForAlignment(data_size)),
        key_size_(RoundUpForAlignment(key_size)),
        erase_size_(chunk_header_size_ + key_size_),
        min_put_size_(
            RoundUpForAlignment(chunk_header_size_ + key_size_ + data_size_)) {}

  size_t ChunkHeaderSize() { return chunk_header_size_; }
  size_t DataSize() { return data_size_; }
  size_t KeySize() { return key_size_; }
  size_t EraseSize() { return erase_size_; }
  size_t MinPutSize() { return min_put_size_; }

 private:
  const size_t chunk_header_size_;
  const size_t data_size_;
  const size_t key_size_;
  const size_t erase_size_;
  const size_t min_put_size_;
};

class EmptyInitializedKvs : public ::testing::Test {
 protected:
  EmptyInitializedKvs() : kvs_(&test_partition, format) {
    test_partition.Erase();
    ASSERT_EQ(Status::OK, kvs_.Init());
  }

  // Intention of this is to put and erase key-val to fill up sectors. It's a
  // helper function in testing how KVS handles cases where flash sector is full
  // or near full.
  void FillKvs(const char* key, size_t size_to_fill) {
    constexpr size_t kTestDataSize = 8;
    KvsAttributes kvs_attr(std::strlen(key), kTestDataSize);
    const size_t kMaxPutSize =
        buffer.size() + kvs_attr.ChunkHeaderSize() + kvs_attr.KeySize();

    ASSERT_GE(size_to_fill, kvs_attr.MinPutSize() + kvs_attr.EraseSize());

    // Saving enough space to perform erase after loop
    size_to_fill -= kvs_attr.EraseSize();
    // We start with possible small chunk to prevent too small of a Kvs.Put() at
    // the end.
    size_t chunk_len =
        std::max(kvs_attr.MinPutSize(), size_to_fill % buffer.size());
    std::memset(buffer.data(), 0, buffer.size());
    while (size_to_fill > 0) {
      // Changing buffer value so put actually does something
      buffer[0] = static_cast<byte>(static_cast<uint8_t>(buffer[0]) + 1);
      ASSERT_EQ(Status::OK,
                kvs_.Put(key,
                         span(buffer.data(),
                              chunk_len - kvs_attr.ChunkHeaderSize() -
                                  kvs_attr.KeySize())));
      size_to_fill -= chunk_len;
      chunk_len = std::min(size_to_fill, kMaxPutSize);
    }
    ASSERT_EQ(Status::OK, kvs_.Delete(key));
  }

  KeyValueStoreBuffer<kMaxEntries, kMaxUsableSectors> kvs_;
};

uint16_t CalcKvsCrc(const char* key, const void* data, size_t data_len) {
  uint16_t crc = checksum::CcittCrc16(as_bytes(span(key, std::strlen(key))));
  return checksum::CcittCrc16(span(static_cast<const byte*>(data), data_len),
                              crc);
}

uint16_t CalcTestPartitionCrc() {
  byte buf[16];  // Read as 16 byte chunks
  EXPECT_EQ(sizeof(buf) % test_partition.alignment_bytes(), 0u);
  EXPECT_EQ(test_partition.size_bytes() % sizeof(buf), 0u);
  uint16_t crc = checksum::kCcittCrc16DefaultInitialValue;
  for (size_t i = 0; i < test_partition.size_bytes(); i += sizeof(buf)) {
    test_partition.Read(i, buf);
    crc = checksum::CcittCrc16(as_bytes(span(buf)), crc);
  }
  return crc;
}

}  // namespace

TEST_F(EmptyInitializedKvs, Put_SameKeySameValueRepeatedly_AlignedEntries) {
  std::array<char, 8> value{'v', 'a', 'l', 'u', 'e', '6', '7', '\0'};

  for (int i = 0; i < 1000; ++i) {
    ASSERT_EQ(Status::OK, kvs_.Put("The Key!", as_bytes(span(value))));
  }
}

TEST_F(EmptyInitializedKvs, Put_SameKeySameValueRepeatedly_UnalignedEntries) {
  std::array<char, 7> value{'v', 'a', 'l', 'u', 'e', '6', '\0'};

  for (int i = 0; i < 1000; ++i) {
    ASSERT_EQ(Status::OK, kvs_.Put("The Key!", as_bytes(span(value))));
  }
}

TEST_F(EmptyInitializedKvs, Put_SameKeyDifferentValuesRepeatedly) {
  std::array<char, 10> value{'v', 'a', 'l', 'u', 'e', '6', '7', '8', '9', '\0'};

  for (int i = 0; i < 100; ++i) {
    for (unsigned size = 0; size < value.size(); ++size) {
      ASSERT_EQ(Status::OK, kvs_.Put("The Key!", i));
    }
  }
}

TEST_F(EmptyInitializedKvs, Put_MaxValueSize) {
  size_t max_value_size =
      test_partition.sector_size_bytes() - sizeof(EntryHeader) - 1;

  // Use the large_test_flash as a big chunk of data for the Put statement.
  ASSERT_GT(sizeof(large_test_flash), max_value_size + 2 * sizeof(EntryHeader));
  auto big_data = as_bytes(span(&large_test_flash, 1));

  EXPECT_EQ(Status::OK, kvs_.Put("K", big_data.subspan(0, max_value_size)));

  // Larger than maximum is rejected.
  EXPECT_EQ(Status::INVALID_ARGUMENT,
            kvs_.Put("K", big_data.subspan(0, max_value_size + 1)));
  EXPECT_EQ(Status::INVALID_ARGUMENT, kvs_.Put("K", big_data));
}

TEST_F(EmptyInitializedKvs, Get_Simple) {
  ASSERT_EQ(Status::OK, kvs_.Put("Charles", as_bytes(span("Mingus"))));

  char value[16];
  auto result = kvs_.Get("Charles", as_writable_bytes(span(value)));
  EXPECT_EQ(Status::OK, result.status());
  EXPECT_EQ(sizeof("Mingus"), result.size());
  EXPECT_STREQ("Mingus", value);
}

TEST_F(EmptyInitializedKvs, Get_WithOffset) {
  ASSERT_EQ(Status::OK, kvs_.Put("Charles", as_bytes(span("Mingus"))));

  char value[16];
  auto result = kvs_.Get("Charles", as_writable_bytes(span(value)), 4);
  EXPECT_EQ(Status::OK, result.status());
  EXPECT_EQ(sizeof("Mingus") - 4, result.size());
  EXPECT_STREQ("us", value);
}

TEST_F(EmptyInitializedKvs, Get_WithOffset_FillBuffer) {
  ASSERT_EQ(Status::OK, kvs_.Put("Charles", as_bytes(span("Mingus"))));

  char value[4] = {};
  auto result = kvs_.Get("Charles", as_writable_bytes(span(value, 3)), 1);
  EXPECT_EQ(Status::RESOURCE_EXHAUSTED, result.status());
  EXPECT_EQ(3u, result.size());
  EXPECT_STREQ("ing", value);
}

TEST_F(EmptyInitializedKvs, Get_WithOffset_PastEnd) {
  ASSERT_EQ(Status::OK, kvs_.Put("Charles", as_bytes(span("Mingus"))));

  char value[16];
  auto result =
      kvs_.Get("Charles", as_writable_bytes(span(value)), sizeof("Mingus") + 1);
  EXPECT_EQ(Status::OUT_OF_RANGE, result.status());
  EXPECT_EQ(0u, result.size());
}

TEST_F(EmptyInitializedKvs, Delete_GetDeletedKey_ReturnsNotFound) {
  ASSERT_EQ(Status::OK, kvs_.Put("kEy", as_bytes(span("123"))));
  ASSERT_EQ(Status::OK, kvs_.Delete("kEy"));

  EXPECT_EQ(Status::NOT_FOUND, kvs_.Get("kEy", {}).status());
  EXPECT_EQ(Status::NOT_FOUND, kvs_.ValueSize("kEy").status());
}

TEST_F(EmptyInitializedKvs, Delete_AddBackKey_PersistsAfterInitialization) {
  ASSERT_EQ(Status::OK, kvs_.Put("kEy", as_bytes(span("123"))));
  ASSERT_EQ(Status::OK, kvs_.Delete("kEy"));

  EXPECT_EQ(Status::OK, kvs_.Put("kEy", as_bytes(span("45678"))));
  char data[6] = {};
  ASSERT_EQ(Status::OK, kvs_.Get("kEy", &data));
  EXPECT_STREQ(data, "45678");

  // Ensure that the re-added key is still present after reinitialization.
  KeyValueStoreBuffer<kMaxEntries, kMaxUsableSectors> new_kvs(&test_partition,
                                                              format);
  ASSERT_EQ(Status::OK, new_kvs.Init());

  EXPECT_EQ(Status::OK, new_kvs.Put("kEy", as_bytes(span("45678"))));
  char new_data[6] = {};
  EXPECT_EQ(Status::OK, new_kvs.Get("kEy", &new_data));
  EXPECT_STREQ(data, "45678");
}

TEST_F(EmptyInitializedKvs, Delete_AllItems_KvsIsEmpty) {
  ASSERT_EQ(Status::OK, kvs_.Put("kEy", as_bytes(span("123"))));
  ASSERT_EQ(Status::OK, kvs_.Delete("kEy"));

  EXPECT_EQ(0u, kvs_.size());
  EXPECT_TRUE(kvs_.empty());
}

TEST_F(EmptyInitializedKvs, Collision_WithPresentKey) {
  // Both hash to 0x19df36f0.
  constexpr std::string_view key1 = "D4";
  constexpr std::string_view key2 = "dFU6S";

  ASSERT_EQ(Status::OK, kvs_.Put(key1, 1000));

  EXPECT_EQ(Status::ALREADY_EXISTS, kvs_.Put(key2, 999));

  int value = 0;
  EXPECT_EQ(Status::OK, kvs_.Get(key1, &value));
  EXPECT_EQ(1000, value);

  EXPECT_EQ(Status::NOT_FOUND, kvs_.Get(key2, &value));
  EXPECT_EQ(Status::NOT_FOUND, kvs_.ValueSize(key2).status());
  EXPECT_EQ(Status::NOT_FOUND, kvs_.Delete(key2));
}

TEST_F(EmptyInitializedKvs, Collision_WithDeletedKey) {
  // Both hash to 0x4060f732.
  constexpr std::string_view key1 = "1U2";
  constexpr std::string_view key2 = "ahj9d";

  ASSERT_EQ(Status::OK, kvs_.Put(key1, 1000));
  ASSERT_EQ(Status::OK, kvs_.Delete(key1));

  // key2 collides with key1's tombstone.
  EXPECT_EQ(Status::ALREADY_EXISTS, kvs_.Put(key2, 999));

  int value = 0;
  EXPECT_EQ(Status::NOT_FOUND, kvs_.Get(key1, &value));

  EXPECT_EQ(Status::NOT_FOUND, kvs_.Get(key2, &value));
  EXPECT_EQ(Status::NOT_FOUND, kvs_.ValueSize(key2).status());
  EXPECT_EQ(Status::NOT_FOUND, kvs_.Delete(key2));
}

TEST_F(EmptyInitializedKvs, Iteration_Empty_ByReference) {
  for (const KeyValueStore::Item& entry : kvs_) {
    FAIL();  // The KVS is empty; this shouldn't execute.
    static_cast<void>(entry);
  }
}

TEST_F(EmptyInitializedKvs, Iteration_Empty_ByValue) {
  for (KeyValueStore::Item entry : kvs_) {
    FAIL();  // The KVS is empty; this shouldn't execute.
    static_cast<void>(entry);
  }
}

TEST_F(EmptyInitializedKvs, Iteration_OneItem) {
  ASSERT_EQ(Status::OK, kvs_.Put("kEy", as_bytes(span("123"))));

  for (KeyValueStore::Item entry : kvs_) {
    EXPECT_STREQ(entry.key(), "kEy");  // Make sure null-terminated.

    char buffer[sizeof("123")] = {};
    EXPECT_EQ(Status::OK, entry.Get(&buffer));
    EXPECT_STREQ("123", buffer);
  }
}

TEST_F(EmptyInitializedKvs, Iteration_GetWithOffset) {
  ASSERT_EQ(Status::OK, kvs_.Put("key", as_bytes(span("not bad!"))));

  for (KeyValueStore::Item entry : kvs_) {
    char buffer[5];
    auto result = entry.Get(as_writable_bytes(span(buffer)), 4);
    EXPECT_EQ(Status::OK, result.status());
    EXPECT_EQ(5u, result.size());
    EXPECT_STREQ("bad!", buffer);
  }
}

TEST_F(EmptyInitializedKvs, Iteration_EmptyAfterDeletion) {
  ASSERT_EQ(Status::OK, kvs_.Put("kEy", as_bytes(span("123"))));
  ASSERT_EQ(Status::OK, kvs_.Delete("kEy"));

  for (KeyValueStore::Item entry : kvs_) {
    static_cast<void>(entry);
    FAIL();
  }
}

TEST_F(EmptyInitializedKvs, FuzzTest) {
  if (test_partition.sector_size_bytes() < 4 * 1024 ||
      test_partition.sector_count() < 4) {
    PW_LOG_INFO("Sectors too small, skipping test.");
    return;  // TODO: Test could be generalized
  }
  const char* key1 = "Buf1";
  const char* key2 = "Buf2";
  const size_t kLargestBufSize = 3 * 1024;
  static byte buf1[kLargestBufSize];
  static byte buf2[kLargestBufSize];
  std::memset(buf1, 1, sizeof(buf1));
  std::memset(buf2, 2, sizeof(buf2));

  // Start with things in KVS
  ASSERT_EQ(Status::OK, kvs_.Put(key1, buf1));
  ASSERT_EQ(Status::OK, kvs_.Put(key2, buf2));
  for (size_t j = 0; j < keys.size(); j++) {
    ASSERT_EQ(Status::OK, kvs_.Put(keys[j], j));
  }

  for (size_t i = 0; i < 100; i++) {
    // Vary two sizes
    size_t size1 = (kLargestBufSize) / (i + 1);
    size_t size2 = (kLargestBufSize) / (100 - i);
    for (size_t j = 0; j < 50; j++) {
      // Rewrite a single key many times, can fill up a sector
      ASSERT_EQ(Status::OK, kvs_.Put("some_data", j));
    }
    // Delete and re-add everything
    ASSERT_EQ(Status::OK, kvs_.Delete(key1));
    ASSERT_EQ(Status::OK, kvs_.Put(key1, span(buf1, size1)));
    ASSERT_EQ(Status::OK, kvs_.Delete(key2));
    ASSERT_EQ(Status::OK, kvs_.Put(key2, span(buf2, size2)));
    for (size_t j = 0; j < keys.size(); j++) {
      ASSERT_EQ(Status::OK, kvs_.Delete(keys[j]));
      ASSERT_EQ(Status::OK, kvs_.Put(keys[j], j));
    }

    // Re-enable and verify
    ASSERT_EQ(Status::OK, kvs_.Init());
    static byte buf[4 * 1024];
    ASSERT_EQ(Status::OK, kvs_.Get(key1, span(buf, size1)).status());
    ASSERT_EQ(std::memcmp(buf, buf1, size1), 0);
    ASSERT_EQ(Status::OK, kvs_.Get(key2, span(buf, size2)).status());
    ASSERT_EQ(std::memcmp(buf2, buf2, size2), 0);
    for (size_t j = 0; j < keys.size(); j++) {
      size_t ret = 1000;
      ASSERT_EQ(Status::OK, kvs_.Get(keys[j], &ret));
      ASSERT_EQ(ret, j);
    }
  }
}

TEST_F(EmptyInitializedKvs, Basic) {
  // Add some data
  uint8_t value1 = 0xDA;
  ASSERT_EQ(Status::OK,
            kvs_.Put(keys[0], as_bytes(span(&value1, sizeof(value1)))));

  uint32_t value2 = 0xBAD0301f;
  ASSERT_EQ(Status::OK, kvs_.Put(keys[1], value2));

  // Verify data
  uint32_t test2;
  EXPECT_EQ(Status::OK, kvs_.Get(keys[1], &test2));
  uint8_t test1;
  ASSERT_EQ(Status::OK, kvs_.Get(keys[0], &test1));

  EXPECT_EQ(test1, value1);
  EXPECT_EQ(test2, value2);

  // Delete a key
  EXPECT_EQ(Status::OK, kvs_.Delete(keys[0]));

  // Verify it was erased
  EXPECT_EQ(kvs_.Get(keys[0], &test1), Status::NOT_FOUND);
  test2 = 0;
  ASSERT_EQ(
      Status::OK,
      kvs_.Get(keys[1], span(reinterpret_cast<byte*>(&test2), sizeof(test2)))
          .status());
  EXPECT_EQ(test2, value2);

  // Delete other key
  kvs_.Delete(keys[1]);

  // Verify it was erased
  EXPECT_EQ(kvs_.size(), 0u);
}

#define ASSERT_OK(expr) ASSERT_EQ(Status::OK, expr)
#define EXPECT_OK(expr) EXPECT_EQ(Status::OK, expr)

TEST(InMemoryKvs, WriteOneKeyMultipleTimes) {
  // Create and erase the fake flash. It will persist across reloads.
  Flash flash;
  ASSERT_OK(flash.partition.Erase());

  int num_reloads = 2;
  for (int reload = 0; reload < num_reloads; ++reload) {
    DBG("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
    DBG("xxx                                      xxxx");
    DBG("xxx               Reload %2d              xxxx", reload);
    DBG("xxx                                      xxxx");
    DBG("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

    // Create and initialize the KVS.
    constexpr EntryHeaderFormat format{.magic = 0xBAD'C0D3,
                                       .checksum = nullptr};
    KeyValueStoreBuffer<kMaxEntries, kMaxUsableSectors> kvs(&flash.partition,
                                                            format);
    ASSERT_OK(kvs.Init());

    // Write the same entry many times.
    const char* key = "abcd";
    const size_t num_writes = 1;  // TODO: Make this > 1 when things work.
    uint32_t written_value;
    EXPECT_EQ(kvs.size(), (reload == 0) ? 0 : 1u);
    for (uint32_t i = 0; i < num_writes; ++i) {
      INF("PUT #%zu for key %s with value %zu", size_t(i), key, size_t(i));

      written_value = i + 0xfc;  // Prevent accidental pass with zero.
      EXPECT_OK(kvs.Put(key, written_value));
      EXPECT_EQ(kvs.size(), 1u);
    }

    // Verify that we can read the value back.
    INF("GET final value for key: %s", key);
    uint32_t actual_value;
    EXPECT_OK(kvs.Get(key, &actual_value));
    EXPECT_EQ(actual_value, written_value);

    kvs.LogDebugInfo();

    char fname_buf[64] = {'\0'};
    snprintf(&fname_buf[0],
             sizeof(fname_buf),
             "WriteOneKeyMultipleTimes_%d.bin",
             reload);
    flash.Dump(fname_buf);
  }
}

TEST(InMemoryKvs, WritingMultipleKeysIncreasesSize) {
  // Create and erase the fake flash.
  Flash flash;
  ASSERT_OK(flash.partition.Erase());

  // Create and initialize the KVS.
  constexpr EntryHeaderFormat format{.magic = 0xBAD'C0D3, .checksum = nullptr};
  KeyValueStoreBuffer<kMaxEntries, kMaxUsableSectors> kvs(&flash.partition,
                                                          format);
  ASSERT_OK(kvs.Init());

  // Write the same entry many times.
  const size_t num_writes = 10;
  EXPECT_EQ(kvs.size(), 0u);
  for (size_t i = 0; i < num_writes; ++i) {
    StringBuffer<150> key;
    key << "key_" << i;
    INF("PUT #%zu for key %s with value %zu", i, key.c_str(), i);

    size_t value = i + 77;  // Prevent accidental pass with zero.
    EXPECT_OK(kvs.Put(key.view(), value));
    EXPECT_EQ(kvs.size(), i + 1);
  }
  kvs.LogDebugInfo();
  flash.Dump("WritingMultipleKeysIncreasesSize.bin");
}

TEST(InMemoryKvs, WriteAndReadOneKey) {
  // Create and erase the fake flash.
  Flash flash;
  ASSERT_OK(flash.partition.Erase());

  // Create and initialize the KVS.
  constexpr EntryHeaderFormat format{.magic = 0xBAD'C0D3, .checksum = nullptr};
  KeyValueStoreBuffer<kMaxEntries, kMaxUsableSectors> kvs(&flash.partition,
                                                          format);
  ASSERT_OK(kvs.Init());

  // Add two entries with different keys and values.
  const char* key = "Key1";
  INF("PUT value for key: %s", key);
  uint8_t written_value = 0xDA;
  ASSERT_OK(kvs.Put(key, written_value));
  EXPECT_EQ(kvs.size(), 1u);

  INF("GET value for key: %s", key);
  uint8_t actual_value;
  ASSERT_OK(kvs.Get(key, &actual_value));
  EXPECT_EQ(actual_value, written_value);

  EXPECT_EQ(kvs.size(), 1u);
}

TEST(InMemoryKvs, Basic) {
  const char* key1 = "Key1";
  const char* key2 = "Key2";

  // Create and erase the fake flash.
  Flash flash;
  ASSERT_EQ(Status::OK, flash.partition.Erase());

  // Create and initialize the KVS.
  constexpr EntryHeaderFormat format{.magic = 0xBAD'C0D3, .checksum = nullptr};
  KeyValueStoreBuffer<kMaxEntries, kMaxUsableSectors> kvs(&flash.partition,
                                                          format);
  ASSERT_OK(kvs.Init());

  // Add two entries with different keys and values.
  INF("PUT first value");
  uint8_t value1 = 0xDA;
  ASSERT_OK(kvs.Put(key1, as_bytes(span(&value1, sizeof(value1)))));
  EXPECT_EQ(kvs.size(), 1u);

  INF("PUT second value");
  uint32_t value2 = 0xBAD0301f;
  ASSERT_OK(kvs.Put(key2, value2));
  EXPECT_EQ(kvs.size(), 2u);

  INF("--------------------------------");
  INF("GET second value");
  // Verify data
  uint32_t test2;
  EXPECT_OK(kvs.Get(key2, &test2));

  INF("GET first value");
  uint8_t test1;
  ASSERT_OK(kvs.Get(key1, &test1));

  EXPECT_EQ(test1, value1);
  EXPECT_EQ(test2, value2);

  EXPECT_EQ(kvs.size(), 2u);
}

TEST_F(EmptyInitializedKvs, MaxKeyLength) {
  // Add some data
  char key[16] = "123456789abcdef";  // key length 15 (without \0)
  int value = 1;
  ASSERT_EQ(Status::OK, kvs_.Put(key, value));

  // Verify data
  int test = 0;
  ASSERT_EQ(Status::OK, kvs_.Get(key, &test));
  EXPECT_EQ(test, value);

  // Delete a key
  EXPECT_EQ(Status::OK, kvs_.Delete(key));

  // Verify it was erased
  EXPECT_EQ(kvs_.Get(key, &test), Status::NOT_FOUND);
}

TEST_F(EmptyInitializedKvs, LargeBuffers) {
  // Note this assumes that no other keys larger then key0
  static_assert(sizeof(keys[0]) >= sizeof(keys[1]) &&
                sizeof(keys[0]) >= sizeof(keys[2]));
  KvsAttributes kvs_attr(std::strlen(keys[0]), buffer.size());

  // Verify the data will fit in this test partition. This checks that all the
  // keys chunks will fit and a header for each sector will fit. It requires 1
  // empty sector also.
  const size_t kMinSize = kvs_attr.MinPutSize() * keys.size();
  const size_t kAvailSectorSpace =
      test_partition.sector_size_bytes() * (test_partition.sector_count() - 1);
  if (kAvailSectorSpace < kMinSize) {
    PW_LOG_INFO("KVS too small, skipping test.");
    return;
  }

  // Add and verify
  for (unsigned add_idx = 0; add_idx < keys.size(); add_idx++) {
    std::memset(buffer.data(), add_idx, buffer.size());
    ASSERT_EQ(Status::OK, kvs_.Put(keys[add_idx], buffer));
    EXPECT_EQ(kvs_.size(), add_idx + 1);
    for (unsigned verify_idx = 0; verify_idx <= add_idx; verify_idx++) {
      std::memset(buffer.data(), 0, buffer.size());
      ASSERT_EQ(Status::OK, kvs_.Get(keys[verify_idx], buffer).status());
      for (unsigned i = 0; i < buffer.size(); i++) {
        EXPECT_EQ(static_cast<unsigned>(buffer[i]), verify_idx);
      }
    }
  }

  // Erase and verify
  for (unsigned erase_idx = 0; erase_idx < keys.size(); erase_idx++) {
    ASSERT_EQ(Status::OK, kvs_.Delete(keys[erase_idx]));
    EXPECT_EQ(kvs_.size(), keys.size() - erase_idx - 1);
    for (unsigned verify_idx = 0; verify_idx < keys.size(); verify_idx++) {
      std::memset(buffer.data(), 0, buffer.size());
      if (verify_idx <= erase_idx) {
        ASSERT_EQ(kvs_.Get(keys[verify_idx], buffer).status(),
                  Status::NOT_FOUND);
      } else {
        ASSERT_EQ(Status::OK, kvs_.Get(keys[verify_idx], buffer).status());
        for (uint32_t i = 0; i < buffer.size(); i++) {
          EXPECT_EQ(buffer[i], static_cast<byte>(verify_idx));
        }
      }
    }
  }
}

TEST_F(EmptyInitializedKvs, Enable) {
  KvsAttributes kvs_attr(std::strlen(keys[0]), buffer.size());

  // Verify the data will fit in this test partition. This checks that all the
  // keys chunks will fit and a header for each sector will fit. It requires 1
  // empty sector also.
  const size_t kMinSize = kvs_attr.MinPutSize() * keys.size();
  const size_t kAvailSectorSpace =
      test_partition.sector_size_bytes() * (test_partition.sector_count() - 1);
  if (kAvailSectorSpace < kMinSize) {
    PW_LOG_INFO("KVS too small, skipping test.");
    return;
  }

  // Add some items
  for (unsigned add_idx = 0; add_idx < keys.size(); add_idx++) {
    std::memset(buffer.data(), add_idx, buffer.size());
    ASSERT_EQ(Status::OK, kvs_.Put(keys[add_idx], buffer));
    EXPECT_EQ(kvs_.size(), add_idx + 1);
  }

  // Enable different KVS which should be able to properly setup the same map
  // from what is stored in flash.
  static KeyValueStoreBuffer<kMaxEntries, kMaxUsableSectors> kvs_local(
      &test_partition, format);
  ASSERT_EQ(Status::OK, kvs_local.Init());
  EXPECT_EQ(kvs_local.size(), keys.size());

  // Ensure adding to new KVS works
  uint8_t value = 0xDA;
  const char* key = "new_key";
  ASSERT_EQ(Status::OK, kvs_local.Put(key, value));
  uint8_t test;
  ASSERT_EQ(Status::OK, kvs_local.Get(key, &test));
  EXPECT_EQ(value, test);
  EXPECT_EQ(kvs_local.size(), keys.size() + 1);

  // Verify previous data
  for (unsigned verify_idx = 0; verify_idx < keys.size(); verify_idx++) {
    std::memset(buffer.data(), 0, buffer.size());
    ASSERT_EQ(Status::OK, kvs_local.Get(keys[verify_idx], buffer).status());
    for (uint32_t i = 0; i < buffer.size(); i++) {
      EXPECT_EQ(static_cast<unsigned>(buffer[i]), verify_idx);
    }
  }
}

TEST_F(EmptyInitializedKvs, MultiSector) {
  // Calculate number of elements to ensure multiple sectors are required.
  uint16_t add_count = (test_partition.sector_size_bytes() / buffer.size()) + 1;

  if (kvs_.max_size() < add_count) {
    PW_LOG_INFO("Sector size too large, skipping test.");
    return;  // this chip has very large sectors, test won't work
  }
  if (test_partition.sector_count() < 3) {
    PW_LOG_INFO("Not enough sectors, skipping test.");
    return;  // need at least 3 sectors for multi-sector test
  }

  char key[20];
  for (unsigned add_idx = 0; add_idx < add_count; add_idx++) {
    std::memset(buffer.data(), add_idx, buffer.size());
    snprintf(key, sizeof(key), "key_%u", add_idx);
    ASSERT_EQ(Status::OK, kvs_.Put(key, buffer));
    EXPECT_EQ(kvs_.size(), add_idx + 1);
  }

  for (unsigned verify_idx = 0; verify_idx < add_count; verify_idx++) {
    std::memset(buffer.data(), 0, buffer.size());
    snprintf(key, sizeof(key), "key_%u", verify_idx);
    ASSERT_EQ(Status::OK, kvs_.Get(key, buffer).status());
    for (uint32_t i = 0; i < buffer.size(); i++) {
      EXPECT_EQ(static_cast<unsigned>(buffer[i]), verify_idx);
    }
  }

  // Check erase
  for (unsigned erase_idx = 0; erase_idx < add_count; erase_idx++) {
    snprintf(key, sizeof(key), "key_%u", erase_idx);
    ASSERT_EQ(Status::OK, kvs_.Delete(key));
    EXPECT_EQ(kvs_.size(), add_count - erase_idx - 1);
  }
}

TEST_F(EmptyInitializedKvs, RewriteValue) {
  // Write first value
  const uint8_t kValue1 = 0xDA;
  const uint8_t kValue2 = 0x12;
  const char* key = "the_key";
  ASSERT_EQ(Status::OK, kvs_.Put(key, as_bytes(span(&kValue1, 1))));

  // Verify
  uint8_t value;
  ASSERT_EQ(Status::OK,
            kvs_.Get(key, as_writable_bytes(span(&value, 1))).status());
  EXPECT_EQ(kValue1, value);

  // Write new value for key
  ASSERT_EQ(Status::OK, kvs_.Put(key, as_bytes(span(&kValue2, 1))));

  // Verify
  ASSERT_EQ(Status::OK,
            kvs_.Get(key, as_writable_bytes(span(&value, 1))).status());
  EXPECT_EQ(kValue2, value);

  // Verify only 1 element exists
  EXPECT_EQ(kvs_.size(), 1u);
}

TEST_F(EmptyInitializedKvs, RepeatingValueWithOtherData) {
  std::byte set_buf[150];
  std::byte get_buf[sizeof(set_buf)];

  for (size_t set_index = 0; set_index < sizeof(set_buf); set_index++) {
    set_buf[set_index] = static_cast<std::byte>(set_index);
  }

  StatusWithSize result;

  // Test setting the same entry 10 times but varying the amount of data
  // that is already in env before each test
  for (size_t test_iteration = 0; test_iteration < sizeof(set_buf);
       test_iteration++) {
    // TOD0: Add KVS erase
    // Add a constant unchanging entry so that the updates are not
    // the only entries in the env.  The size of this initial entry
    // we vary between no bytes to sizeof(set_buf).
    ASSERT_EQ(Status::OK,
              kvs_.Put("const_entry", span(set_buf, test_iteration)));

    // The value we read back should be the last value we set
    std::memset(get_buf, 0, sizeof(get_buf));
    result = kvs_.Get("const_entry", span(get_buf));
    ASSERT_EQ(Status::OK, result.status());
    ASSERT_EQ(result.size(), test_iteration);
    for (size_t j = 0; j < test_iteration; j++) {
      EXPECT_EQ(set_buf[j], get_buf[j]);
    }

    // Update the test entry 5 times
    static_assert(sizeof(std::byte) == sizeof(uint8_t));
    uint8_t set_entry_buf[]{1, 2, 3, 4, 5, 6, 7, 8};
    std::byte* set_entry = reinterpret_cast<std::byte*>(set_entry_buf);
    std::byte get_entry_buf[sizeof(set_entry_buf)];
    for (size_t i = 0; i < 5; i++) {
      set_entry[0] = static_cast<std::byte>(i);
      ASSERT_EQ(Status::OK,
                kvs_.Put("test_entry", span(set_entry, sizeof(set_entry_buf))));
      std::memset(get_entry_buf, 0, sizeof(get_entry_buf));
      result = kvs_.Get("test_entry", span(get_entry_buf));
      ASSERT_TRUE(result.ok());
      ASSERT_EQ(result.size(), sizeof(get_entry_buf));
      for (uint32_t j = 0; j < sizeof(set_entry_buf); j++) {
        EXPECT_EQ(set_entry[j], get_entry_buf[j]);
      }
    }

    // Check that the const entry is still present and has the right value
    std::memset(get_buf, 0, sizeof(get_buf));
    result = kvs_.Get("const_entry", span(get_buf));
    ASSERT_TRUE(result.ok());
    ASSERT_EQ(result.size(), test_iteration);
    for (size_t j = 0; j < test_iteration; j++) {
      EXPECT_EQ(set_buf[j], get_buf[j]);
    }
  }
}

#if 0  // Offset reads are not yet supported

TEST_F(EmptyInitializedKvs, OffsetRead) {
  const char* key = "the_key";
  constexpr size_t kReadSize = 16;  // needs to be a multiple of alignment
  constexpr size_t kTestBufferSize = kReadSize * 10;
  ASSERT_GT(buffer.size(), kTestBufferSize);
  ASSERT_LE(kTestBufferSize, 0xFF);

  // Write the entire buffer
  for (size_t i = 0; i < kTestBufferSize; i++) {
    buffer[i] = byte(i);
  }
  ASSERT_EQ(Status::OK, kvs_.Put(key, span(buffer.data(), kTestBufferSize)));
  EXPECT_EQ(kvs_.size(), 1u);

  // Read in small chunks and verify
  for (unsigned i = 0; i < kTestBufferSize / kReadSize; i++) {
    std::memset(buffer.data(), 0, buffer.size());
    ASSERT_EQ(
        Status::OK,
        kvs_.Get(key, span(buffer.data(), kReadSize), i * kReadSize).status());
    for (unsigned j = 0; j < kReadSize; j++) {
      ASSERT_EQ(static_cast<unsigned>(buffer[j]), j + i * kReadSize);
    }
  }
}
#endif

TEST_F(EmptyInitializedKvs, MultipleRewrite) {
  // Calculate number of elements to ensure multiple sectors are required.
  unsigned add_count = (test_partition.sector_size_bytes() / buffer.size()) + 1;

  const char* key = "the_key";
  constexpr uint8_t kGoodVal = 0x60;
  constexpr uint8_t kBadVal = 0xBA;
  std::memset(buffer.data(), kBadVal, buffer.size());
  for (unsigned add_idx = 0; add_idx < add_count; add_idx++) {
    if (add_idx == add_count - 1) {  // last value
      std::memset(buffer.data(), kGoodVal, buffer.size());
    }
    ASSERT_EQ(Status::OK, kvs_.Put(key, buffer));
    EXPECT_EQ(kvs_.size(), 1u);
  }

  // Verify
  std::memset(buffer.data(), 0, buffer.size());
  ASSERT_EQ(Status::OK, kvs_.Get(key, buffer).status());
  for (uint32_t i = 0; i < buffer.size(); i++) {
    ASSERT_EQ(buffer[i], static_cast<byte>(kGoodVal));
  }
}

TEST_F(EmptyInitializedKvs, FillSector) {
  ASSERT_EQ(std::strlen(keys[0]), 8U);  // Easier for alignment
  ASSERT_EQ(std::strlen(keys[2]), 8U);  // Easier for alignment
  constexpr size_t kTestDataSize = 8;
  KvsAttributes kvs_attr(std::strlen(keys[2]), kTestDataSize);
  int bytes_remaining = test_partition.sector_size_bytes();
  constexpr byte kKey0Pattern = byte{0xBA};

  std::memset(
      buffer.data(), static_cast<int>(kKey0Pattern), kvs_attr.DataSize());
  ASSERT_EQ(Status::OK,
            kvs_.Put(keys[0], span(buffer.data(), kvs_attr.DataSize())));
  bytes_remaining -= kvs_attr.MinPutSize();
  std::memset(buffer.data(), 1, kvs_attr.DataSize());
  ASSERT_EQ(Status::OK,
            kvs_.Put(keys[2], span(buffer.data(), kvs_attr.DataSize())));
  bytes_remaining -= kvs_attr.MinPutSize();
  EXPECT_EQ(kvs_.size(), 2u);
  ASSERT_EQ(Status::OK, kvs_.Delete(keys[2]));
  bytes_remaining -= kvs_attr.EraseSize();
  EXPECT_EQ(kvs_.size(), 1u);

  // Intentionally adding erase size to trigger sector cleanup
  bytes_remaining += kvs_attr.EraseSize();
  FillKvs(keys[2], bytes_remaining);

  // Verify key[0]
  std::memset(buffer.data(), 0, kvs_attr.DataSize());
  ASSERT_EQ(
      Status::OK,
      kvs_.Get(keys[0], span(buffer.data(), kvs_attr.DataSize())).status());
  for (uint32_t i = 0; i < kvs_attr.DataSize(); i++) {
    EXPECT_EQ(buffer[i], kKey0Pattern);
  }
}

TEST_F(EmptyInitializedKvs, Interleaved) {
  const uint8_t kValue1 = 0xDA;
  const uint8_t kValue2 = 0x12;
  uint8_t value;
  ASSERT_EQ(Status::OK, kvs_.Put(keys[0], kValue1));
  EXPECT_EQ(kvs_.size(), 1u);
  ASSERT_EQ(Status::OK, kvs_.Delete(keys[0]));
  EXPECT_EQ(kvs_.Get(keys[0], &value), Status::NOT_FOUND);
  ASSERT_EQ(Status::OK, kvs_.Put(keys[1], as_bytes(span(&kValue1, 1))));
  ASSERT_EQ(Status::OK, kvs_.Put(keys[2], kValue2));
  ASSERT_EQ(Status::OK, kvs_.Delete(keys[1]));
  EXPECT_EQ(Status::OK, kvs_.Get(keys[2], &value));
  EXPECT_EQ(kValue2, value);

  EXPECT_EQ(kvs_.size(), 1u);
}

TEST_F(EmptyInitializedKvs, DeleteAndReinitialize) {
  // Write value
  const uint8_t kValue = 0xDA;
  ASSERT_EQ(Status::OK, kvs_.Put(keys[0], kValue));

  ASSERT_EQ(Status::OK, kvs_.Delete(keys[0]));
  uint8_t value;
  ASSERT_EQ(kvs_.Get(keys[0], &value), Status::NOT_FOUND);

  // Reset KVS, ensure captured at enable
  ASSERT_EQ(Status::OK, kvs_.Init());

  ASSERT_EQ(kvs_.Get(keys[0], &value), Status::NOT_FOUND);
}

TEST_F(EmptyInitializedKvs, TemplatedPutAndGet) {
  // Store a value with the convenience method.
  const uint32_t kValue = 0x12345678;
  ASSERT_EQ(Status::OK, kvs_.Put(keys[0], kValue));

  // Read it back with the other convenience method.
  uint32_t value;
  ASSERT_EQ(Status::OK, kvs_.Get(keys[0], &value));
  ASSERT_EQ(kValue, value);

  // Make sure we cannot get something where size isn't what we expect
  const uint8_t kSmallValue = 0xBA;
  uint8_t small_value = kSmallValue;
  ASSERT_EQ(kvs_.Get(keys[0], &small_value), Status::INVALID_ARGUMENT);
  ASSERT_EQ(small_value, kSmallValue);
}

// This test is derived from bug that was discovered. Testing this corner case
// relies on creating a new key-value just under the size that is left over in
// the sector.
TEST_F(EmptyInitializedKvs, FillSector2) {
  if (test_partition.sector_count() < 3) {
    PW_LOG_INFO("Not enough sectors, skipping test.");
    return;  // need at least 3 sectors
  }

  // Start of by filling flash sector to near full
  constexpr int kHalfBufferSize = buffer.size() / 2;
  const int kSizeToFill = test_partition.sector_size_bytes() - kHalfBufferSize;
  constexpr size_t kTestDataSize = 8;
  KvsAttributes kvs_attr(std::strlen(keys[2]), kTestDataSize);

  FillKvs(keys[2], kSizeToFill);

  // Find out how much space is remaining for new key-value and confirm it
  // makes sense.
  size_t new_keyvalue_size = 0;
  size_t alignment = test_partition.alignment_bytes();
  // Starts on second sector since it will try to keep first sector free
  FlashPartition::Address read_address =
      2 * test_partition.sector_size_bytes() - alignment;
  for (; read_address > 0; read_address -= alignment) {
    bool is_erased = false;
    ASSERT_EQ(
        Status::OK,
        test_partition.IsRegionErased(read_address, alignment, &is_erased));
    if (is_erased) {
      new_keyvalue_size += alignment;
    } else {
      break;
    }
  }

  size_t expected_remaining = test_partition.sector_size_bytes() - kSizeToFill;
  ASSERT_EQ(new_keyvalue_size, expected_remaining);

  const char* kNewKey = "NewKey";
  constexpr size_t kValueLessThanChunkHeaderSize = 2;
  constexpr auto kTestPattern = byte{0xBA};
  new_keyvalue_size -= kValueLessThanChunkHeaderSize;
  std::memset(buffer.data(), static_cast<int>(kTestPattern), new_keyvalue_size);
  ASSERT_EQ(Status::OK,
            kvs_.Put(kNewKey, span(buffer.data(), new_keyvalue_size)));

  // In failed corner case, adding new key is deceptively successful. It isn't
  // until KVS is disabled and reenabled that issue can be detected.
  ASSERT_EQ(Status::OK, kvs_.Init());

  // Might as well check that new key-value is what we expect it to be
  ASSERT_EQ(Status::OK,
            kvs_.Get(kNewKey, span(buffer.data(), new_keyvalue_size)).status());
  for (size_t i = 0; i < new_keyvalue_size; i++) {
    EXPECT_EQ(buffer[i], kTestPattern);
  }
}

TEST_F(EmptyInitializedKvs, ValueSize_Positive) {
  constexpr auto kData = AsBytes('h', 'i', '!');
  ASSERT_EQ(Status::OK, kvs_.Put("TheKey", kData));

  auto result = kvs_.ValueSize("TheKey");

  EXPECT_EQ(Status::OK, result.status());
  EXPECT_EQ(kData.size(), result.size());
}

TEST_F(EmptyInitializedKvs, ValueSize_Zero) {
  ASSERT_EQ(Status::OK, kvs_.Put("TheKey", as_bytes(span("123", 3))));
  auto result = kvs_.ValueSize("TheKey");

  EXPECT_EQ(Status::OK, result.status());
  EXPECT_EQ(3u, result.size());
}

TEST_F(EmptyInitializedKvs, ValueSize_InvalidKey) {
  EXPECT_EQ(Status::INVALID_ARGUMENT, kvs_.ValueSize("").status());
}

TEST_F(EmptyInitializedKvs, ValueSize_MissingKey) {
  EXPECT_EQ(Status::NOT_FOUND, kvs_.ValueSize("Not in there").status());
}

TEST_F(EmptyInitializedKvs, ValueSize_DeletedKey) {
  ASSERT_EQ(Status::OK, kvs_.Put("TheKey", as_bytes(span("123", 3))));
  ASSERT_EQ(Status::OK, kvs_.Delete("TheKey"));

  EXPECT_EQ(Status::NOT_FOUND, kvs_.ValueSize("TheKey").status());
}

#if USE_MEMORY_BUFFER

class LargeEmptyInitializedKvs : public ::testing::Test {
 protected:
  LargeEmptyInitializedKvs() : kvs_(&large_test_partition, format) {
    ASSERT_EQ(
        Status::OK,
        large_test_partition.Erase(0, large_test_partition.sector_count()));
    ASSERT_EQ(Status::OK, kvs_.Init());
  }

  KeyValueStoreBuffer<kMaxEntries, kMaxUsableSectors> kvs_;
};

TEST_F(LargeEmptyInitializedKvs, Basic) {
  const uint8_t kValue1 = 0xDA;
  const uint8_t kValue2 = 0x12;
  uint8_t value;
  ASSERT_EQ(Status::OK, kvs_.Put(keys[0], kValue1));
  EXPECT_EQ(kvs_.size(), 1u);
  ASSERT_EQ(Status::OK, kvs_.Delete(keys[0]));
  EXPECT_EQ(kvs_.Get(keys[0], &value), Status::NOT_FOUND);
  ASSERT_EQ(Status::OK, kvs_.Put(keys[1], kValue1));
  ASSERT_EQ(Status::OK, kvs_.Put(keys[2], kValue2));
  ASSERT_EQ(Status::OK, kvs_.Delete(keys[1]));
  EXPECT_EQ(Status::OK, kvs_.Get(keys[2], &value));
  EXPECT_EQ(kValue2, value);
  ASSERT_EQ(kvs_.Get(keys[1], &value), Status::NOT_FOUND);
  EXPECT_EQ(kvs_.size(), 1u);
}

#endif  // USE_MEMORY_BUFFER

TEST_F(EmptyInitializedKvs, DifferentValueSameCrc16) {
  const char kKey[] = "k";
  // With the key and our CRC16 algorithm these both have CRC of 0x82AE
  // Given they are the same size and same key, the KVS will need to check
  // the actual bits to know they are different.
  const char kValue1[] = {'d', 'a', 't'};
  const char kValue2[] = {'u', 'c', 'd'};

  // Verify the CRC matches
  ASSERT_EQ(CalcKvsCrc(kKey, kValue1, sizeof(kValue1)),
            CalcKvsCrc(kKey, kValue2, sizeof(kValue2)));

  ASSERT_EQ(Status::OK, kvs_.Put(kKey, kValue1));

  // Now try to rewrite with the similar value.
  ASSERT_EQ(Status::OK, kvs_.Put(kKey, kValue2));

  // Read it back and check it is correct
  char value[3] = {};
  ASSERT_EQ(Status::OK, kvs_.Get(kKey, &value));
  ASSERT_EQ(std::memcmp(value, kValue2, sizeof(value)), 0);
}

TEST_F(EmptyInitializedKvs, CallingEraseTwice) {
  const uint8_t kValue = 0xDA;
  ASSERT_EQ(Status::OK, kvs_.Put(keys[0], kValue));
  ASSERT_EQ(Status::OK, kvs_.Delete(keys[0]));
  uint16_t crc = CalcTestPartitionCrc();
  EXPECT_EQ(kvs_.Delete(keys[0]), Status::NOT_FOUND);
  // Verify the flash has not changed
  EXPECT_EQ(crc, CalcTestPartitionCrc());
}

#if 0  // TODO: not CanFitEntry function yet
TEST_F(EmptyInitializedKvs, DISABLED_CanFitEntryTests) {
  // Get exactly the number of bytes that can fit in the space remaining for
  // a large value, accounting for alignment.
  constexpr uint16_t kTestKeySize = 2;
  size_t space_remaining =
      test_partition.sector_size_bytes()          //
      - RoundUpForAlignment(sizeof(EntryHeader))  // TODO: Sector Header
      - RoundUpForAlignment(sizeof(EntryHeader))  // Cleaning Header
      - RoundUpForAlignment(sizeof(EntryHeader))  // TODO: Chunk Header
      - RoundUpForAlignment(kTestKeySize);
  space_remaining -= test_partition.alignment_bytes() / 2;
  space_remaining = RoundUpForAlignment(space_remaining);

  EXPECT_TRUE(kvs_.CanFitEntry(kTestKeySize, space_remaining));
  EXPECT_FALSE(kvs_.CanFitEntry(kTestKeySize, space_remaining + 1));
}
#endif

void __attribute__((noinline)) StackHeavyPartialClean() {
#if 0  // TODO: No FlashSubPartition

  ASSERT_GE(test_partition.sector_count(), 2);
  FlashSubPartition test_partition_sector1(&test_partition, 0, 1);
  FlashSubPartition test_partition_sector2(&test_partition, 1, 1);

  KeyValueStore kvs1(&test_partition_sector1);
  KeyValueStore kvs2(&test_partition_sector2);

  test_partition.Erase(0, test_partition.sector_count());

  ASSERT_EQ(Status::OK, kvs1.Enable());
  ASSERT_EQ(Status::OK, kvs2.Enable());

  int values1[3] = {100, 101, 102};
  ASSERT_EQ(Status::OK, kvs1.Put(keys[0], values1[0]));
  ASSERT_EQ(Status::OK, kvs1.Put(keys[1], values1[1]));
  ASSERT_EQ(Status::OK, kvs1.Put(keys[2], values1[2]));

  int values2[3] = {200, 201, 202};
  ASSERT_EQ(Status::OK, kvs2.Put(keys[0], values2[0]));
  ASSERT_EQ(Status::OK, kvs2.Put(keys[1], values2[1]));
  ASSERT_EQ(Status::OK, kvs2.Delete(keys[1]));

  kvs1.Disable();
  kvs2.Disable();

  // Key 0 is value1 in first sector, value 2 in second
  // Key 1 is value1 in first sector, erased in second
  // key 2 is only in first sector

  uint64_t mark_clean_count = 5;
  ASSERT_EQ(Status::OK,
            PaddedWrite(&test_partition_sector1,
                        RoundUpForAlignment(KeyValueStore::kHeaderSize),
                        reinterpret_cast<uint8_t*>(&mark_clean_count),
                        sizeof(uint64_t)));

  // Reset KVS
  kvs_.Disable();
  ASSERT_EQ(Status::OK, kvs_.Init());
  int value;
  ASSERT_EQ(Status::OK, kvs_.Get(keys[0], &value));
  ASSERT_EQ(values2[0], value);
  ASSERT_EQ(kvs_.Get(keys[1], &value), Status::NOT_FOUND);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[2], &value));
  ASSERT_EQ(values1[2], value);

  if (test_partition.sector_count() == 2) {
    EXPECT_EQ(kvs_.PendingCleanCount(), 0u);
    // Has forced a clean, mark again for next test
    return;  // Not enough sectors to test 2 partial cleans.
  } else {
    EXPECT_EQ(kvs_.PendingCleanCount(), 1u);
  }

  mark_clean_count--;
  ASSERT_EQ(Status::OK,
            PaddedWrite(&test_partition_sector2,
                        RoundUpForAlignment(KeyValueStore::kHeaderSize),
                        reinterpret_cast<uint8_t*>(&mark_clean_count),
                        sizeof(uint64_t)));
  // Reset KVS
  kvs_.Disable();
  ASSERT_EQ(Status::OK, kvs_.Init());
  EXPECT_EQ(kvs_.PendingCleanCount(), 2u);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[0], &value));
  ASSERT_EQ(values1[0], value);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[1], &value));
  ASSERT_EQ(values1[1], value);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[2], &value));
  ASSERT_EQ(values1[2], value);
#endif
}

// TODO: This doesn't do anything, and would be unreliable anyway.
size_t CurrentTaskStackFree() { return -1; }

TEST_F(EmptyInitializedKvs, DISABLED_PartialClean) {
  if (CurrentTaskStackFree() < sizeof(KeyValueStore) * 2) {
    PW_LOG_ERROR("Not enough stack for test, skipping");
    return;
  }
  StackHeavyPartialClean();
}

void __attribute__((noinline)) StackHeavyCleanAll() {
#if 0  // TODO: no FlashSubPartition
  ASSERT_GE(test_partition.sector_count(), 2);
  FlashSubPartition test_partition_sector1(&test_partition, 0, 1);

  KeyValueStore kvs1(&test_partition_sector1);
  test_partition.Erase(0, test_partition.sector_count());

  ASSERT_EQ(Status::OK, kvs1.Enable());

  int values1[3] = {100, 101, 102};
  ASSERT_EQ(Status::OK, kvs1.Put(keys[0], values1[0]));
  ASSERT_EQ(Status::OK, kvs1.Put(keys[1], values1[1]));
  ASSERT_EQ(Status::OK,
            kvs1.Put(keys[2], values1[2] - 100));  //  force a rewrite
  ASSERT_EQ(Status::OK, kvs1.Put(keys[2], values1[2]));

  kvs1.Disable();

  uint64_t mark_clean_count = 5;
  ASSERT_EQ(Status::OK,
            PaddedWrite(&test_partition_sector1,
                        RoundUpForAlignment(KeyValueStore::kHeaderSize),
                        reinterpret_cast<uint8_t*>(&mark_clean_count),
                        sizeof(uint64_t)));

  // Reset KVS
  kvs_.Disable();
  ASSERT_EQ(Status::OK, kvs_.Init());
  int value;
  EXPECT_EQ(kvs_.PendingCleanCount(), 1u);
  ASSERT_EQ(Status::OK, kvs_.CleanAll());
  EXPECT_EQ(kvs_.PendingCleanCount(), 0u);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[0], &value));
  ASSERT_EQ(values1[0], value);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[1], &value));
  ASSERT_EQ(values1[1], value);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[2], &value));
  ASSERT_EQ(values1[2], value);
#endif
}

TEST_F(EmptyInitializedKvs, DISABLED_CleanAll) {
  if (CurrentTaskStackFree() < sizeof(KeyValueStore) * 1) {
    PW_LOG_ERROR("Not enough stack for test, skipping");
    return;
  }
  StackHeavyCleanAll();
}

void __attribute__((noinline)) StackHeavyPartialCleanLargeCounts() {
#if 0
  ASSERT_GE(test_partition.sector_count(), 2);
  FlashSubPartition test_partition_sector1(&test_partition, 0, 1);
  FlashSubPartition test_partition_sector2(&test_partition, 1, 1);

  KeyValueStore kvs1(&test_partition_sector1);
  KeyValueStore kvs2(&test_partition_sector2);

  test_partition.Erase(0, test_partition.sector_count());

  ASSERT_EQ(Status::OK, kvs1.Enable());
  ASSERT_EQ(Status::OK, kvs2.Enable());

  int values1[3] = {100, 101, 102};
  ASSERT_EQ(Status::OK, kvs1.Put(keys[0], values1[0]));
  ASSERT_EQ(Status::OK, kvs1.Put(keys[1], values1[1]));
  ASSERT_EQ(Status::OK, kvs1.Put(keys[2], values1[2]));

  int values2[3] = {200, 201, 202};
  ASSERT_EQ(Status::OK, kvs2.Put(keys[0], values2[0]));
  ASSERT_EQ(Status::OK, kvs2.Put(keys[1], values2[1]));
  ASSERT_EQ(Status::OK, kvs2.Delete(keys[1]));

  kvs1.Disable();
  kvs2.Disable();
  kvs_.Disable();

  // Key 0 is value1 in first sector, value 2 in second
  // Key 1 is value1 in first sector, erased in second
  // key 2 is only in first sector

  uint64_t mark_clean_count = 4569877515;
  ASSERT_EQ(Status::OK,
            PaddedWrite(&test_partition_sector1,
                        RoundUpForAlignment(KeyValueStore::kHeaderSize),
                        reinterpret_cast<uint8_t*>(&mark_clean_count),
                        sizeof(uint64_t)));

  // Reset KVS
  ASSERT_EQ(Status::OK, kvs_.Init());
  int value;
  ASSERT_EQ(Status::OK, kvs_.Get(keys[0], &value));
  ASSERT_EQ(values2[0], value);
  ASSERT_EQ(kvs_.Get(keys[1], &value), Status::NOT_FOUND);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[2], &value));
  ASSERT_EQ(values1[2], value);

  if (test_partition.sector_count() == 2) {
    EXPECT_EQ(kvs_.PendingCleanCount(), 0u);
    // Has forced a clean, mark again for next test
    // Has forced a clean, mark again for next test
    return;  // Not enough sectors to test 2 partial cleans.
  } else {
    EXPECT_EQ(kvs_.PendingCleanCount(), 1u);
  }
  kvs_.Disable();

  mark_clean_count--;
  ASSERT_EQ(Status::OK,
            PaddedWrite(&test_partition_sector2,
                        RoundUpForAlignment(KeyValueStore::kHeaderSize),
                        reinterpret_cast<uint8_t*>(&mark_clean_count),
                        sizeof(uint64_t)));
  // Reset KVS
  ASSERT_EQ(Status::OK, kvs_.Init());
  EXPECT_EQ(kvs_.PendingCleanCount(), 2u);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[0], &value));
  ASSERT_EQ(values1[0], value);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[1], &value));
  ASSERT_EQ(values1[1], value);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[2], &value));
  ASSERT_EQ(values1[2], value);
#endif
}

TEST_F(EmptyInitializedKvs, DISABLED_PartialCleanLargeCounts) {
  if (CurrentTaskStackFree() < sizeof(KeyValueStore) * 2) {
    PW_LOG_ERROR("Not enough stack for test, skipping");
    return;
  }
  StackHeavyPartialCleanLargeCounts();
}

void __attribute__((noinline)) StackHeavyRecoverNoFreeSectors() {
#if 0  // TODO: no FlashSubPartition
  ASSERT_GE(test_partition.sector_count(), 2);
  FlashSubPartition test_partition_sector1(&test_partition, 0, 1);
  FlashSubPartition test_partition_sector2(&test_partition, 1, 1);
  FlashSubPartition test_partition_both(&test_partition, 0, 2);

  KeyValueStore kvs1(&test_partition_sector1);
  KeyValueStore kvs2(&test_partition_sector2);
  KeyValueStore kvs_both(&test_partition_both);

  test_partition.Erase(0, test_partition.sector_count());

  ASSERT_EQ(Status::OK, kvs1.Enable());
  ASSERT_EQ(Status::OK, kvs2.Enable());

  int values[3] = {100, 101};
  ASSERT_EQ(Status::OK, kvs1.Put(keys[0], values[0]));
  ASSERT_FALSE(kvs1.HasEmptySector());
  ASSERT_EQ(Status::OK, kvs2.Put(keys[1], values[1]));
  ASSERT_FALSE(kvs2.HasEmptySector());

  kvs1.Disable();
  kvs2.Disable();

  // Reset KVS
  ASSERT_EQ(Status::OK, kvs_both.Enable());
  ASSERT_TRUE(kvs_both.HasEmptySector());
  int value;
  ASSERT_EQ(Status::OK, kvs_both.Get(keys[0], &value));
  ASSERT_EQ(values[0], value);
  ASSERT_EQ(Status::OK, kvs_both.Get(keys[1], &value));
  ASSERT_EQ(values[1], value);
#endif
}

TEST_F(EmptyInitializedKvs, RecoverNoFreeSectors) {
  if (CurrentTaskStackFree() < sizeof(KeyValueStore) * 3) {
    PW_LOG_ERROR("Not enough stack for test, skipping");
    return;
  }
  StackHeavyRecoverNoFreeSectors();
}

void __attribute__((noinline)) StackHeavyCleanOneSector() {
#if 0  // TODO: no FlashSubPartition
  ASSERT_GE(test_partition.sector_count(), 2);
  FlashSubPartition test_partition_sector1(&test_partition, 0, 1);
  FlashSubPartition test_partition_sector2(&test_partition, 1, 1);

  KeyValueStore kvs1(&test_partition_sector1);

  test_partition.Erase(0, test_partition.sector_count());

  ASSERT_EQ(Status::OK, kvs1.Enable());

  int values[3] = {100, 101, 102};
  ASSERT_EQ(Status::OK, kvs1.Put(keys[0], values[0]));
  ASSERT_EQ(Status::OK, kvs1.Put(keys[1], values[1]));
  ASSERT_EQ(Status::OK, kvs1.Put(keys[2], values[2]));

  kvs1.Disable();
  kvs_.Disable();

  uint64_t mark_clean_count = 1;
  ASSERT_EQ(Status::OK,
            PaddedWrite(&test_partition_sector1,
                        RoundUpForAlignment(KeyValueStore::kHeaderSize),
                        reinterpret_cast<uint8_t*>(&mark_clean_count),
                        sizeof(uint64_t)));

  // Reset KVS
  ASSERT_EQ(Status::OK, kvs_.Init());

  EXPECT_EQ(kvs_.PendingCleanCount(), 1u);

  bool all_sectors_have_been_cleaned = false;
  ASSERT_EQ(Status::OK, kvs_.CleanOneSector(&all_sectors_have_been_cleaned));
  EXPECT_EQ(all_sectors_have_been_cleaned, true);
  EXPECT_EQ(kvs_.PendingCleanCount(), 0u);
  ASSERT_EQ(Status::OK, kvs_.CleanOneSector(&all_sectors_have_been_cleaned));
  EXPECT_EQ(all_sectors_have_been_cleaned, true);
  int value;
  ASSERT_EQ(Status::OK, kvs_.Get(keys[0], &value));
  ASSERT_EQ(values[0], value);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[1], &value));
  ASSERT_EQ(values[1], value);
  ASSERT_EQ(Status::OK, kvs_.Get(keys[2], &value));
  ASSERT_EQ(values[2], value);
#endif
}

TEST_F(EmptyInitializedKvs, DISABLED_CleanOneSector) {
  if (CurrentTaskStackFree() < sizeof(KeyValueStore)) {
    PW_LOG_ERROR("Not enough stack for test, skipping");
    return;
  }
  StackHeavyCleanOneSector();
}

}  // namespace pw::kvs
