// Copyright 2022 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 <algorithm>
#include <array>
#include <cstddef>
#include <cstring>
#include <span>

#include "gtest/gtest.h"
#include "public/pw_kvs/flash_memory.h"
#include "pw_kvs/fake_flash_memory.h"
#include "pw_kvs/flash_memory.h"
#include "pw_kvs_private/config.h"
#include "pw_log/log.h"
#include "pw_random/xor_shift.h"

#if PW_CXX_STANDARD_IS_SUPPORTED(17)

#ifndef PW_FLASH_TEST_ALIGNMENT
#define PW_FLASH_TEST_ALIGNMENT 1
#endif

namespace pw::kvs {
namespace {

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

  void InitBufferToFill(ByteSpan buffer_span, char fill) {
    std::memset(buffer_span.data(), fill, buffer_span.size_bytes());
  }

  void InitBufferToRandom(ByteSpan buffer_span, uint64_t seed) {
    random::XorShiftStarRng64 rng(seed);

    std::memset(buffer_span.data(),
                static_cast<int>(flash_.erased_memory_content()),
                buffer_span.size());
    ASSERT_EQ(OkStatus(), rng.Get(buffer_span).status());
  }

  void VerifyFlash(ConstByteSpan verify_bytes, size_t offset = 0) {
    // 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() + offset), source_buffer_.size());

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

  void VerifyFlashContent(ConstByteSpan verify_bytes, size_t offset = 0) {
    // Can't allow it to march off the end of source_buffer_.
    ASSERT_LE((verify_bytes.size_bytes() + offset),
              flash_.buffer().size_bytes());

    for (size_t i = 0; i < verify_bytes.size_bytes(); i++) {
      ASSERT_EQ(flash_.buffer()[i + offset], verify_bytes[i]);
    }
  }

  void DoWriteInChunks(size_t chunk_write_size_bytes, uint64_t seed) {
    InitBufferToRandom(std::span(source_buffer_), seed);
    ConstByteSpan write_data = std::span(source_buffer_);

    ASSERT_EQ(OkStatus(), partition_.Erase());

    FlashPartition::Writer writer(partition_);

    while (write_data.size_bytes() > 0) {
      size_t offset_before_write = writer.Tell();
      size_t write_chunk_size =
          std::min(chunk_write_size_bytes, write_data.size_bytes());

      ConstByteSpan write_chunk = write_data.first(write_chunk_size);
      ASSERT_EQ(OkStatus(), writer.Write(write_chunk));
      VerifyFlashContent(write_chunk, offset_before_write);

      write_data = write_data.subspan(write_chunk_size);

      ASSERT_EQ(writer.ConservativeWriteLimit(), write_data.size_bytes());
    }

    VerifyFlashContent(std::span(source_buffer_));
  }

  void DoReadInChunks(size_t chunk_read_size_bytes,
                      uint64_t seed,
                      size_t start_offset,
                      size_t bytes_to_read) {
    InitBufferToRandom(flash_.buffer(), seed);

    ASSERT_LE((start_offset + bytes_to_read), flash_.buffer().size_bytes());

    FlashPartition::Reader reader(partition_);
    ASSERT_EQ(reader.ConservativeReadLimit(), flash_.buffer().size_bytes());

    ASSERT_EQ(reader.Seek(start_offset), OkStatus());
    ASSERT_EQ(reader.ConservativeReadLimit(),
              flash_.buffer().size_bytes() - start_offset);

    while (bytes_to_read > 0) {
      ASSERT_EQ(start_offset, reader.Tell());

      size_t chunk_size = std::min(chunk_read_size_bytes, bytes_to_read);

      ByteSpan read_chunk = std::span(source_buffer_).first(chunk_size);
      InitBufferToFill(read_chunk, 0);
      ASSERT_EQ(read_chunk.size_bytes(), chunk_size);

      auto result = reader.Read(read_chunk);
      ASSERT_EQ(result.status(), OkStatus());
      ASSERT_EQ(result.value().size_bytes(), chunk_size);
      VerifyFlashContent(read_chunk, start_offset);

      start_offset += chunk_size;
      bytes_to_read -= chunk_size;

      ASSERT_EQ(reader.ConservativeReadLimit(),
                flash_.buffer().size_bytes() - start_offset);
    }
  }

  static constexpr size_t kFlashAlignment = PW_FLASH_TEST_ALIGNMENT;
  static constexpr size_t kSectorSize = 2048;
  static constexpr size_t kSectorCount = 2;
  static constexpr size_t kFPDataSize = (kSectorCount * kSectorSize);

  FakeFlashMemoryBuffer<kSectorSize, kSectorCount> flash_;
  FlashPartition partition_;
  std::array<std::byte, kFPDataSize> source_buffer_;
  size_t size_bytes_;
};

TEST_F(FlashStreamTest, Write_1_Byte_Chunks) {
  // Write in 1 byte chunks.
  DoWriteInChunks(1, 0xab1234);
}

TEST_F(FlashStreamTest, Write_5_Byte_Chunks) {
  // Write in 5 byte chunks.
  DoWriteInChunks(5, 0xdc2274);
}

TEST_F(FlashStreamTest, Write_16_Byte_Chunks) {
  // Write in 16 byte chunks.
  DoWriteInChunks(16, 0xef8224);
}

TEST_F(FlashStreamTest, Write_255_Byte_Chunks) {
  // Write in 255 byte chunks.
  DoWriteInChunks(255, 0xffe1348);
}

TEST_F(FlashStreamTest, Write_256_Byte_Chunks) {
  // Write in 256 byte chunks.
  DoWriteInChunks(256, 0xe11234);
}

TEST_F(FlashStreamTest, Read_1_Byte_Chunks) {
  // Read in 1 byte chunks.
  DoReadInChunks(1, 0x7643ff, 0, flash_.buffer().size_bytes());
}

TEST_F(FlashStreamTest, Read_16_Byte_Chunks) {
  // Read in 16 byte chunks.
  DoReadInChunks(16, 0x61e234, 0, flash_.buffer().size_bytes());
}

TEST_F(FlashStreamTest, Read_255_Byte_Chunks) {
  // Read in 256 byte chunks.
  DoReadInChunks(255, 0xe13514, 0, flash_.buffer().size_bytes());
}

TEST_F(FlashStreamTest, Read_256_Byte_Chunks) {
  // Read in 256 byte chunks.
  DoReadInChunks(256, 0xe11234, 0, flash_.buffer().size_bytes());
}

TEST_F(FlashStreamTest, Read_256_Byte_Chunks_With_Offset) {
  // Read in 256 byte chunks.
  DoReadInChunks(256, 0xfffe34, 1024, (flash_.buffer().size_bytes() - 1024));
}

TEST_F(FlashStreamTest, Read_Multiple_Seeks) {
  static const size_t kSeekReadSizeBytes = 512;
  static const size_t kSeekReadIterations = 4;
  ASSERT_GE(flash_.buffer().size_bytes(),
            (kSeekReadIterations * (2 * kSeekReadSizeBytes)));

  InitBufferToRandom(flash_.buffer(), 0xffde176);
  FlashPartition::Reader reader(partition_);

  for (size_t i = 0; i < kSeekReadIterations; i++) {
    size_t start_offset = kSeekReadSizeBytes + (i * 2 * kSeekReadSizeBytes);
    ASSERT_EQ(reader.Seek(start_offset), OkStatus());
    ASSERT_EQ(start_offset, reader.Tell());

    ByteSpan read_chunk = std::span(source_buffer_).first(kSeekReadSizeBytes);
    InitBufferToFill(read_chunk, 0);

    auto result = reader.Read(read_chunk);
    ASSERT_EQ(result.status(), OkStatus());
    ASSERT_EQ(result.value().size_bytes(), kSeekReadSizeBytes);
    VerifyFlashContent(read_chunk, start_offset);
    ASSERT_EQ(start_offset + kSeekReadSizeBytes, reader.Tell());
  }
}

TEST_F(FlashStreamTest, Read_Seek_Forward_and_Back) {
  static const size_t kSeekReadSizeBytes = 256;
  static const size_t kTotalIterations = 3;
  static const size_t kSeekReadIterations =
      flash_.buffer().size_bytes() / (2 * kSeekReadSizeBytes);

  InitBufferToRandom(flash_.buffer(), 0xffde176);
  FlashPartition::Reader reader(partition_);

  for (size_t outer_count = 0; outer_count < kTotalIterations; outer_count++) {
    // Seek and read going forward.
    for (size_t i = 0; i < kSeekReadIterations; i++) {
      size_t start_offset = kSeekReadSizeBytes + (i * 2 * kSeekReadSizeBytes);
      ASSERT_EQ(reader.Seek(start_offset), OkStatus());
      ASSERT_EQ(start_offset, reader.Tell());

      ByteSpan read_chunk = std::span(source_buffer_).first(kSeekReadSizeBytes);
      InitBufferToFill(read_chunk, 0);

      auto result = reader.Read(read_chunk);
      ASSERT_EQ(result.status(), OkStatus());
      ASSERT_EQ(result.value().size_bytes(), kSeekReadSizeBytes);
      VerifyFlashContent(read_chunk, start_offset);
      ASSERT_EQ(start_offset + kSeekReadSizeBytes, reader.Tell());
    }

    // Seek and read going backward.
    for (size_t j = (kSeekReadIterations * 2); j > 0; j--) {
      size_t start_offset = (j - 1) * kSeekReadSizeBytes;
      ASSERT_EQ(reader.Seek(start_offset), OkStatus());
      ASSERT_EQ(start_offset, reader.Tell());
      ASSERT_GE(reader.ConservativeReadLimit(), kSeekReadSizeBytes);

      ByteSpan read_chunk = std::span(source_buffer_).first(kSeekReadSizeBytes);
      InitBufferToFill(read_chunk, 0);

      auto result = reader.Read(read_chunk);
      ASSERT_EQ(result.status(), OkStatus());
      ASSERT_EQ(result.value().size_bytes(), kSeekReadSizeBytes);
      VerifyFlashContent(read_chunk, start_offset);
      ASSERT_EQ(start_offset + kSeekReadSizeBytes, reader.Tell());
    }
  }
}

TEST_F(FlashStreamTest, Read_Past_End) {
  InitBufferToRandom(flash_.buffer(), 0xcccde176);
  FlashPartition::Reader reader(partition_);

  static const size_t kBytesForFinalRead = 50;

  ByteSpan read_chunk = std::span(source_buffer_)
                            .first(source_buffer_.size() - kBytesForFinalRead);

  auto result = reader.Read(read_chunk);
  ASSERT_EQ(result.status(), OkStatus());
  ASSERT_EQ(result.value().size_bytes(), read_chunk.size_bytes());
  ASSERT_EQ(reader.Tell(), read_chunk.size_bytes());
  ASSERT_EQ(reader.ConservativeReadLimit(), kBytesForFinalRead);
  ASSERT_EQ(result.value().data(), read_chunk.data());
  VerifyFlashContent(read_chunk);

  result = reader.Read(read_chunk);
  ASSERT_EQ(result.status(), OkStatus());
  ASSERT_EQ(result.value().size_bytes(), kBytesForFinalRead);
  ASSERT_EQ(reader.Tell(), flash_.buffer().size_bytes());
  ASSERT_EQ(reader.ConservativeReadLimit(), 0U);
  ASSERT_EQ(result.value().data(), read_chunk.data());
  VerifyFlashContent(result.value(), read_chunk.size_bytes());
}

TEST_F(FlashStreamTest, Read_Past_End_After_Seek) {
  InitBufferToRandom(flash_.buffer(), 0xddcde176);
  FlashPartition::Reader reader(partition_);

  static const size_t kBytesForFinalRead = 50;
  size_t start_offset = flash_.buffer().size_bytes() - kBytesForFinalRead;
  ASSERT_EQ(reader.Seek(start_offset), OkStatus());

  ASSERT_EQ(start_offset, reader.Tell());
  ASSERT_EQ(reader.ConservativeReadLimit(), kBytesForFinalRead);

  ByteSpan read_chunk = std::span(source_buffer_);
  auto result = reader.Read(read_chunk);
  ASSERT_EQ(result.status(), OkStatus());
  ASSERT_EQ(result.value().size_bytes(), kBytesForFinalRead);
  ASSERT_EQ(reader.Tell(), flash_.buffer().size_bytes());
  ASSERT_EQ(reader.ConservativeReadLimit(), 0U);
  ASSERT_EQ(result.value().data(), read_chunk.data());
  VerifyFlashContent(result.value(), start_offset);
}

TEST_F(FlashStreamTest, Read_Out_Of_Range) {
  InitBufferToRandom(flash_.buffer(), 0x531de176);
  FlashPartition::Reader reader(partition_);

  ByteSpan read_chunk = std::span(source_buffer_);

  auto result = reader.Read(read_chunk);
  ASSERT_EQ(result.status(), OkStatus());
  ASSERT_EQ(result.value().size_bytes(), read_chunk.size_bytes());
  ASSERT_EQ(reader.Tell(), read_chunk.size_bytes());
  ASSERT_EQ(reader.ConservativeReadLimit(), 0U);
  ASSERT_EQ(result.value().data(), read_chunk.data());
  VerifyFlashContent(read_chunk);

  result = reader.Read(read_chunk);
  ASSERT_EQ(result.status(), Status::OutOfRange());
  ASSERT_EQ(reader.Tell(), flash_.buffer().size_bytes());
  ASSERT_EQ(reader.ConservativeReadLimit(), 0U);
}

TEST_F(FlashStreamTest, Read_Out_Of_Range_After_Seek) {
  InitBufferToRandom(flash_.buffer(), 0x8c94566);
  FlashPartition::Reader reader(partition_);

  ByteSpan read_chunk = std::span(source_buffer_);

  ASSERT_EQ(reader.Seek(flash_.buffer().size_bytes()), OkStatus());
  ASSERT_EQ(reader.Tell(), flash_.buffer().size_bytes());
  ASSERT_EQ(reader.ConservativeReadLimit(), 0U);

  auto result = reader.Read(read_chunk);
  ASSERT_EQ(result.status(), Status::OutOfRange());
  ASSERT_EQ(reader.Tell(), flash_.buffer().size_bytes());
  ASSERT_EQ(reader.ConservativeReadLimit(), 0U);
}

TEST_F(FlashStreamTest, Reader_Seek_Ops) {
  size_t kPartitionSizeBytes = flash_.buffer().size_bytes();
  FlashPartition::Reader reader(partition_);

  // Seek from 0 to past end.
  ASSERT_EQ(reader.Seek(kPartitionSizeBytes + 5), Status::OutOfRange());
  ASSERT_EQ(reader.Tell(), 0U);

  // Seek to end then seek again going past end.
  ASSERT_EQ(reader.Seek(0), OkStatus());
  ASSERT_EQ(reader.Tell(), 0U);
  ASSERT_EQ(reader.ConservativeReadLimit(), kPartitionSizeBytes);

  ASSERT_EQ(reader.Seek(kPartitionSizeBytes,
                        FlashPartition::Reader::Whence::kCurrent),
            OkStatus());
  ASSERT_EQ(reader.Tell(), kPartitionSizeBytes);
  ASSERT_EQ(reader.ConservativeReadLimit(), 0U);

  ASSERT_EQ(reader.Seek(5, FlashPartition::Reader::Whence::kCurrent),
            Status::OutOfRange());
  ASSERT_EQ(reader.Tell(), kPartitionSizeBytes);
  ASSERT_EQ(reader.ConservativeReadLimit(), 0U);

  // Seek to beginning then seek backwards going past start.
  ASSERT_EQ(reader.Seek(0), OkStatus());
  ASSERT_EQ(reader.Seek(-5, FlashPartition::Reader::Whence::kCurrent),
            Status::OutOfRange());
  ASSERT_EQ(reader.Tell(), 0U);
  ASSERT_EQ(reader.ConservativeReadLimit(), kPartitionSizeBytes);
}

TEST_F(FlashStreamTest, Invald_Ops) {
  FlashPartition::Reader reader(partition_);
  ASSERT_EQ(reader.ConservativeWriteLimit(), 0U);

  FlashPartition::Writer writer(partition_);
  ASSERT_EQ(writer.ConservativeReadLimit(), 0U);
}

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

#endif  // PW_CXX_STANDARD_IS_SUPPORTED(17)
