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

// Always use stats, these tests depend on it.
#define PW_KVS_RECORD_PARTITION_STATS 1

#include "gtest/gtest.h"
#include "pw_kvs/fake_flash_memory.h"
#include "pw_kvs/flash_memory.h"
#include "pw_kvs/flash_partition_with_stats.h"
#include "pw_kvs/key_value_store.h"
#include "pw_log/log.h"

namespace pw::kvs {
namespace {

// For KVS magic value always use a random 32 bit integer rather than a
// human readable 4 bytes. See pw_kvs/format.h for more information.
constexpr EntryFormat format{.magic = 0x1bce4ad5, .checksum = nullptr};

class WearTest : public ::testing::Test {
 protected:
  WearTest()
      : flash_(internal::Entry::kMinAlignmentBytes),
        partition_(&flash_, 0, flash_.sector_count()),
        kvs_(&partition_, format) {
    EXPECT_EQ(Status::Ok(), kvs_.Init());
  }

  static constexpr size_t kSectors = 16;
  static constexpr size_t kMaxEntries = 256;
  static constexpr size_t kTestPartitionSectorSize = 512;

  FakeFlashMemoryBuffer<kTestPartitionSectorSize, kSectors> flash_;
  FlashPartitionWithStatsBuffer<kSectors> partition_;

  KeyValueStoreBuffer<kMaxEntries, kSectors> kvs_;
};

// Block of data to use for entry value. Sized to 470 so the total entry results
// in using most of the 512 byte sector.
uint8_t test_data[470] = {1, 2, 3, 4, 5, 6};

// Write a large key (i.e. only one entry fits in each sector) enough times to
// fill up the KVS multiple times, and ensure every sector was garbage collected
// multiple additional times.
TEST_F(WearTest, RepeatedLargeEntry) {
  // Initialize an empty KVS, erasing flash and all tracked sector erase counts.
  partition_.ResetCounters();

  // Add enough large entries to fill the entire KVS several times.
  for (size_t i = 0; i < kSectors * 10; ++i) {
    // modify the value to ensure a key-value different than was previously
    // written.
    test_data[0]++;

    EXPECT_TRUE(kvs_.Put("large_entry", std::span(test_data)).ok());
  }

  // Ensure every sector has been erased at several times due to garbage
  // collection.
  EXPECT_GE(partition_.min_erase_count(), 7u);
  EXPECT_LE(partition_.max_erase_count(), partition_.min_erase_count() + 1u);

  partition_.SaveStorageStats(kvs_, "WearTest RepeatedLargeEntry");
}

// Test a KVS with a number of entries, several sectors that are nearly full
// of stale (reclaimable) space, and not enough writable (free) space to add a
// redundant copy for any of the entries. Tests that the add redundancy step of
// repair is able to use garbage collection to free up space needed for the new
// copies.
TEST_F(WearTest, TwoPassFillWithLargeAndLarger) {
  partition_.ResetCounters();

  // Add a large entry that will only fit once per sector enough times to fill
  // the KVS with mostly stale data.
  for (size_t i = 0; i < kSectors; i++) {
    // modify the value to ensure a key-value different than was previously
    // written.
    test_data[0]++;

    EXPECT_EQ(
        Status::Ok(),
        kvs_.Put("key",
                 std::as_bytes(std::span(test_data, sizeof(test_data) - 70))));
  }

  // Add many copies of a differently sized entry that is larger than the
  // previous entry.
  for (size_t i = 0; i < kSectors * 200; i++) {
    // Modify the value to ensure a key-value different than was previously
    // written.
    test_data[0]++;

    printf("Add entry %zu\n", i);
    EXPECT_EQ(Status::Ok(), kvs_.Put("big_key", test_data));
  }

  EXPECT_EQ(2u, kvs_.size());
  EXPECT_LT(partition_.max_erase_count(),
            2u * partition_.average_erase_count());
}

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