// 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 <array>
#include <cstddef>
#include <cstring>

#include "gtest/gtest.h"
#include "pw_blob_store/blob_store.h"
#include "pw_kvs/crc16_checksum.h"
#include "pw_kvs/fake_flash_memory.h"
#include "pw_kvs/flash_memory.h"
#include "pw_kvs/test_key_value_store.h"
#include "pw_log/log.h"
#include "pw_random/xor_shift.h"
#include "pw_span/span.h"

namespace pw::blob_store {
namespace {

class DeferredWriteTest : public ::testing::Test {
 protected:
  DeferredWriteTest() : flash_(kFlashAlignment), partition_(&flash_) {}

  void InitFlashToErased() { ASSERT_EQ(OkStatus(), partition_.Erase()); }

  void InitFlashToRandom(uint64_t seed) {
    random::XorShiftStarRng64 rng(seed);
    StatusWithSize sws = rng.Get(flash_.buffer());
    ASSERT_EQ(OkStatus(), sws.status());
    ASSERT_EQ(sws.size(), flash_.buffer().size());
  }

  void InitBufferToRandom(uint64_t seed) {
    random::XorShiftStarRng64 rng(seed);
    StatusWithSize sws = rng.Get(buffer_);
    ASSERT_EQ(OkStatus(), sws.status());
    ASSERT_EQ(sws.size(), buffer_.size());
  }

  void InitBufferToFill(char fill) {
    ASSERT_EQ(OkStatus(), partition_.Erase());
    std::memset(buffer_.data(), fill, buffer_.size());
  }

  // Fill the source buffer with random pattern based on given seed, written to
  // BlobStore in specified chunk size.
  void ChunkWriteTest(size_t chunk_size,
                      size_t flush_interval,
                      bool explicit_discard = false,
                      bool explicit_erase = false) {
    constexpr size_t kWriteSize = 64;
    kvs::ChecksumCrc16 checksum;

    size_t bytes_since_flush = 0;

    char name[16] = {};
    snprintf(name, sizeof(name), "Blob%u", static_cast<unsigned>(chunk_size));

    BlobStoreBuffer<kBufferSize> blob(
        name, partition_, &checksum, kvs::TestKvs(), kWriteSize);
    EXPECT_EQ(OkStatus(), blob.Init());

    BlobStore::DeferredWriterWithBuffer writer(blob);
    EXPECT_EQ(OkStatus(), writer.Open());

    if (explicit_discard) {
      EXPECT_EQ(OkStatus(), writer.Discard());
    }

    if (explicit_erase) {
      EXPECT_EQ(OkStatus(), writer.Erase());
    }

    ByteSpan source = buffer_;
    while (source.size_bytes() > 0) {
      const size_t write_size = std::min(source.size_bytes(), chunk_size);

      PW_LOG_DEBUG("Do write of %u bytes, %u bytes remain",
                   static_cast<unsigned>(write_size),
                   static_cast<unsigned>(source.size_bytes()));

      ASSERT_EQ(OkStatus(), writer.Write(source.first(write_size)));
      // TODO: Add check that the write did not go to flash yet.

      source = source.subspan(write_size);
      bytes_since_flush += write_size;

      if (bytes_since_flush >= flush_interval) {
        bytes_since_flush = 0;
        ASSERT_EQ(OkStatus(), writer.Flush());
      }
    }

    EXPECT_EQ(OkStatus(), writer.Close());

    // Use reader to check for valid data.
    BlobStore::BlobReader reader(blob);
    ASSERT_EQ(OkStatus(), reader.Open());
    Result<ConstByteSpan> result = reader.GetMemoryMappedBlob();
    ASSERT_TRUE(result.ok());
    VerifyFlash(result.value());
    EXPECT_EQ(OkStatus(), reader.Close());
  }

  void VerifyFlash(ConstByteSpan verify_bytes) {
    // Should be defined as same size.
    EXPECT_EQ(buffer_.size(), flash_.buffer().size_bytes());

    // Can't allow it to march off the end of buffer_.
    ASSERT_LE(verify_bytes.size_bytes(), buffer_.size());

    for (size_t i = 0; i < verify_bytes.size_bytes(); i++) {
      EXPECT_EQ(buffer_[i], verify_bytes[i]);
    }
  }

  static constexpr size_t kFlashAlignment = 16;
  static constexpr size_t kSectorSize = 1024;
  static constexpr size_t kSectorCount = 4;
  static constexpr size_t kBufferSize = 2 * kSectorSize;

  kvs::FakeFlashMemoryBuffer<kSectorSize, kSectorCount> flash_;
  kvs::FlashPartition partition_;
  std::array<std::byte, kSectorCount * kSectorSize> buffer_;
};

TEST_F(DeferredWriteTest, ChunkWrite1) {
  InitFlashToErased();
  InitBufferToRandom(0x8675309);
  ChunkWriteTest(1, 16);
}

TEST_F(DeferredWriteTest, ChunkWrite2) {
  InitFlashToRandom(0x2283);
  InitBufferToRandom(0x8675);
  ChunkWriteTest(2, 16);
}

TEST_F(DeferredWriteTest, ChunkWrite3) {
  InitFlashToErased();
  InitBufferToFill(0);
  ChunkWriteTest(3, 16);
}

TEST_F(DeferredWriteTest, ChunkWrite4) {
  InitFlashToErased();
  InitBufferToFill(1);
  ChunkWriteTest(4, 64);
}

TEST_F(DeferredWriteTest, ChunkWrite5) {
  InitFlashToErased();
  InitBufferToFill(0xff);
  ChunkWriteTest(5, 64);
}

TEST_F(DeferredWriteTest, ChunkWrite16) {
  InitFlashToErased();
  InitBufferToRandom(0x86);
  ChunkWriteTest(16, 128);
}

TEST_F(DeferredWriteTest, ChunkWrite64) {
  InitFlashToRandom(0x9223);
  InitBufferToRandom(0x9);
  ChunkWriteTest(64, 128);
}

TEST_F(DeferredWriteTest, ChunkWrite64FullBufferFill) {
  InitFlashToErased();
  InitBufferToRandom(0x9);
  ChunkWriteTest(64, kBufferSize);
}

TEST_F(DeferredWriteTest, ChunkWrite256) {
  InitFlashToErased();
  InitBufferToRandom(0x12345678);
  ChunkWriteTest(256, 256);
}

TEST_F(DeferredWriteTest, ChunkWriteDiscard16) {
  InitFlashToErased();
  InitBufferToRandom(0x86);

  // Test with a discard of an invalid blob and erased flash.
  ChunkWriteTest(16, 128, true);

  // Test with a discard of a valid blob.
  ChunkWriteTest(16, 128, true);

  // Test with a discard of an current blob with corrupted date.
  InitFlashToRandom(0x9223);
  ChunkWriteTest(16, 128, true);
}

TEST_F(DeferredWriteTest, ChunkWriteErase16) {
  InitFlashToErased();
  InitBufferToRandom(0x1286);

  // Test with an erase of an invalid blob and erased flash.
  ChunkWriteTest(16, 128, false, true);

  // Test with an erase of a valid blob.
  ChunkWriteTest(16, 128, false, true);

  // Test with an erase of an current blob with corrupted date.
  InitFlashToRandom(0x9223);
  ChunkWriteTest(16, 128, false, true);
}

}  // namespace
}  // namespace pw::blob_store
