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

#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"

namespace pw::blob_store {
namespace {

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

  void InitFlashTo(std::span<const std::byte> contents) {
    partition_.Erase()
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    std::memcpy(flash_.buffer().data(), contents.data(), contents.size());
  }

  void InitSourceBufferToRandom(uint64_t seed) {
    partition_.Erase()
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    random::XorShiftStarRng64 rng(seed);
    rng.Get(source_buffer_)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  }

  void InitSourceBufferToFill(char fill) {
    partition_.Erase()
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    std::memset(source_buffer_.data(), fill, source_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) {
    constexpr size_t kBufferSize = 256;
    kvs::ChecksumCrc16 checksum;

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

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

    BlobStore::BlobWriter writer(blob, metadata_buffer_);
    EXPECT_EQ(OkStatus(), writer.Open());
    EXPECT_EQ(OkStatus(), writer.Erase());

    ByteSpan source = 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)));

      source = source.subspan(write_size);
    }

    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(source_buffer_.size(), flash_.buffer().size_bytes());

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

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

  static constexpr size_t kFlashAlignment = 16;
  static constexpr size_t kSectorSize = 2048;
  static constexpr size_t kSectorCount = 2;
  static constexpr size_t kBlobDataSize = (kSectorCount * kSectorSize);
  static constexpr size_t kMetadataBufferSize =
      BlobStore::BlobWriter::RequiredMetadataBufferSize(0);

  kvs::FakeFlashMemoryBuffer<kSectorSize, kSectorCount> flash_;
  kvs::FlashPartition partition_;
  std::array<std::byte, kMetadataBufferSize> metadata_buffer_;
  std::array<std::byte, kBlobDataSize> source_buffer_;
};

TEST_F(BlobStoreChunkTest, ChunkWrite1) {
  InitSourceBufferToRandom(0x8675309);
  ChunkWriteTest(1);
}

TEST_F(BlobStoreChunkTest, ChunkWrite2) {
  InitSourceBufferToRandom(0x8675);
  ChunkWriteTest(2);
}

TEST_F(BlobStoreChunkTest, ChunkWrite3) {
  InitSourceBufferToFill(0);
  ChunkWriteTest(3);
}

TEST_F(BlobStoreChunkTest, ChunkWrite4) {
  InitSourceBufferToFill(1);
  ChunkWriteTest(4);
}

TEST_F(BlobStoreChunkTest, ChunkWrite5) {
  InitSourceBufferToFill(0xff);
  ChunkWriteTest(5);
}

TEST_F(BlobStoreChunkTest, ChunkWrite16) {
  InitSourceBufferToRandom(0x86);
  ChunkWriteTest(16);
}

TEST_F(BlobStoreChunkTest, ChunkWrite64) {
  InitSourceBufferToRandom(0x9);
  ChunkWriteTest(64);
}

TEST_F(BlobStoreChunkTest, ChunkWrite256) {
  InitSourceBufferToRandom(0x12345678);
  ChunkWriteTest(256);
}

TEST_F(BlobStoreChunkTest, ChunkWrite512) {
  InitSourceBufferToRandom(0x42);
  ChunkWriteTest(512);
}

TEST_F(BlobStoreChunkTest, ChunkWrite4096) {
  InitSourceBufferToRandom(0x89);
  ChunkWriteTest(4096);
}

TEST_F(BlobStoreChunkTest, ChunkWriteSingleFull) {
  InitSourceBufferToRandom(0x98765);
  ChunkWriteTest(kBlobDataSize);
}

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