// 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.
#pragma once

#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <limits>

#include "pw_assert/assert.h"
#include "pw_kvs/alignment.h"
#include "pw_polyfill/standard.h"
#include "pw_span/span.h"
#include "pw_status/status.h"
#include "pw_status/status_with_size.h"

#if PW_CXX_STANDARD_IS_SUPPORTED(17)  // Requires C++17 for pw::Result
#include "pw_stream/seek.h"
#include "pw_stream/stream.h"
#endif  // PW_CXX_STANDARD_IS_SUPPORTED(17)

namespace pw {
namespace kvs {

enum class PartitionPermission : bool {
  kReadOnly,
  kReadAndWrite,
};

class FlashMemory {
 public:
  // The flash address is in the range of: 0 to FlashSize.
  typedef uint32_t Address;

  // TODO: b/235149326 - This can be constexpr when tokenized asserts are fixed.
  FlashMemory(size_t sector_size,
              size_t sector_count,
              size_t alignment,
              uint32_t start_address = 0,
              uint32_t sector_start = 0,
              std::byte erased_memory_content = std::byte(0xFF))
      : sector_size_(sector_size),
        flash_sector_count_(sector_count),
        alignment_(alignment),
        start_address_(start_address),
        start_sector_(sector_start),
        erased_memory_content_(erased_memory_content) {
    PW_ASSERT(alignment_ != 0u);
  }

  virtual ~FlashMemory() = default;

  virtual Status Enable() = 0;

  virtual Status Disable() = 0;

  virtual bool IsEnabled() const = 0;

  virtual Status SelfTest() { return Status::Unimplemented(); }

  // Erase num_sectors starting at a given address. Blocking call.
  // Address should be on a sector boundary. Returns:
  //
  // OK - success
  // DEADLINE_EXCEEDED - timeout
  // INVALID_ARGUMENT - address is not sector-aligned
  // OUT_OF_RANGE - erases past the end of the memory
  virtual Status Erase(Address flash_address, size_t num_sectors) = 0;

  // Reads bytes from flash into buffer. Blocking call. Returns:
  //
  // OK - success
  // DEADLINE_EXCEEDED - timeout
  // OUT_OF_RANGE - write does not fit in the flash memory
  virtual StatusWithSize Read(Address address, span<std::byte> output) = 0;

  StatusWithSize Read(Address address, void* buffer, size_t len) {
    return Read(address, span<std::byte>(static_cast<std::byte*>(buffer), len));
  }

  // Writes bytes to flash. Blocking call. Returns:
  //
  // OK - success
  // DEADLINE_EXCEEDED - timeout
  // INVALID_ARGUMENT - address or data size are not aligned
  // OUT_OF_RANGE - write does not fit in the memory
  virtual StatusWithSize Write(Address destination_flash_address,
                               span<const std::byte> data) = 0;

  StatusWithSize Write(Address destination_flash_address,
                       const void* data,
                       size_t len) {
    return Write(
        destination_flash_address,
        span<const std::byte>(static_cast<const std::byte*>(data), len));
  }

  // Convert an Address to an MCU pointer, this can be used for memory
  // mapped reads. Return NULL if the memory is not memory mapped.
  virtual std::byte* FlashAddressToMcuAddress(Address) const { return nullptr; }

  // start_sector() is useful for FlashMemory instances where the
  // sector start is not 0. (ex.: cases where there are portions of flash
  // that should be handled independently).
  constexpr uint32_t start_sector() const { return start_sector_; }

  constexpr size_t sector_size_bytes() const { return sector_size_; }

  constexpr size_t sector_count() const { return flash_sector_count_; }

  constexpr size_t alignment_bytes() const { return alignment_; }

  constexpr size_t size_bytes() const {
    return sector_size_ * flash_sector_count_;
  }

  // Address of the start of flash (the address of sector 0)
  constexpr uint32_t start_address() const { return start_address_; }

  constexpr std::byte erased_memory_content() const {
    return erased_memory_content_;
  }

 private:
  const uint32_t sector_size_;
  const uint32_t flash_sector_count_;
  const uint32_t alignment_;
  const uint32_t start_address_;
  const uint32_t start_sector_;
  const std::byte erased_memory_content_;
};

class FlashPartition {
 public:
  // The flash address is in the range of: 0 to PartitionSize.
  using Address = uint32_t;

#if PW_CXX_STANDARD_IS_SUPPORTED(17)  // Requires C++17 for pw::Result
  class Writer final : public stream::NonSeekableWriter {
   public:
    constexpr Writer(kvs::FlashPartition& partition)
        : partition_(partition), position_(0) {}

   private:
    Status DoWrite(ConstByteSpan data) override;

    size_t DoTell() override { return position_; }

    size_t ConservativeLimit(LimitType type) const override {
      return type == LimitType::kWrite ? partition_.size_bytes() - position_
                                       : 0;
    }

    FlashPartition& partition_;
    size_t position_;
  };

  class Reader final : public stream::SeekableReader {
   public:
    /// @brief Stream seekable reader for FlashPartitions.
    ///
    /// @param partition The partiion to read.
    /// @param read_limit_bytes Optional limit to read less than the full
    /// FlashPartition. Reader will use the lesser of read_limit_bytes and
    /// partition size. Situations needing a subset that starts somewhere other
    /// than 0 can seek to the desired start point.
    Reader(kvs::FlashPartition& partition,
           size_t read_limit_bytes = std::numeric_limits<size_t>::max())
        : partition_(partition),
          read_limit_(std::min(read_limit_bytes, partition_.size_bytes())),
          position_(0) {}

    Reader(const Reader&) = delete;
    Reader& operator=(const Reader&) = delete;

    void SetReadLimit(size_t read_limit_bytes) {
      read_limit_ = std::min(read_limit_bytes, partition_.size_bytes());
      position_ = std::min(position_, read_limit_);
    }

   private:
    StatusWithSize DoRead(ByteSpan data) override;

    size_t DoTell() override { return position_; }

    Status DoSeek(ptrdiff_t offset, Whence origin) override {
      return CalculateSeek(offset, origin, read_limit_, position_);
    }

    size_t ConservativeLimit(LimitType type) const override {
      return type == LimitType::kRead ? read_limit_ - position_ : 0;
    }

    FlashPartition& partition_;
    size_t read_limit_;
    size_t position_;
  };
#endif  // PW_CXX_STANDARD_IS_SUPPORTED(17)

  // Implement Output for the Write method.
  class Output final : public pw::Output {
   public:
    constexpr Output(FlashPartition& flash, FlashPartition::Address address)
        : flash_(flash), address_(address) {}

   private:
    StatusWithSize DoWrite(span<const std::byte> data) override;

    FlashPartition& flash_;
    FlashPartition::Address address_;
  };

  // Implement Input for the Read method.
  class Input final : public pw::Input {
   public:
    constexpr Input(FlashPartition& flash, FlashPartition::Address address)
        : flash_(flash), address_(address) {}

   private:
    StatusWithSize DoRead(span<std::byte> data) override;

    FlashPartition& flash_;
    FlashPartition::Address address_;
  };

  FlashPartition(
      FlashMemory* flash,
      uint32_t flash_start_sector_index,
      uint32_t flash_sector_count,
      uint32_t alignment_bytes = 0,  // Defaults to flash alignment
      PartitionPermission permission = PartitionPermission::kReadAndWrite);

  // Creates a FlashPartition that uses the entire flash with its alignment.
  FlashPartition(FlashMemory* flash)
      : FlashPartition(
            flash, 0, flash->sector_count(), flash->alignment_bytes()) {}

  FlashPartition(FlashPartition&&) = default;
  FlashPartition(const FlashPartition&) = delete;
  FlashPartition& operator=(const FlashPartition&) = delete;

  virtual ~FlashPartition() = default;

  // Performs any required partition or flash-level initialization.
  virtual Status Init() { return OkStatus(); }

  // Erase num_sectors starting at a given address. Blocking call.
  // Address must be on a sector boundary. Returns:
  //
  // OK - success.
  // TIMEOUT - on timeout.
  // INVALID_ARGUMENT - address or sector count is invalid.
  // PERMISSION_DENIED - partition is read only.
  // UNKNOWN - HAL error
  virtual Status Erase(Address address, size_t num_sectors);

  Status Erase() { return Erase(0, this->sector_count()); }

  // Reads bytes from flash into buffer. Blocking call. Returns:
  //
  // OK - success.
  // TIMEOUT - on timeout.
  // INVALID_ARGUMENT - address or length is invalid.
  // UNKNOWN - HAL error
  virtual StatusWithSize Read(Address address, span<std::byte> output);

  StatusWithSize Read(Address address, size_t length, void* output) {
    return Read(address,
                span<std::byte>(static_cast<std::byte*>(output), length));
  }

  // Writes bytes to flash. Address and data.size_bytes() must both be a
  // multiple of alignment_bytes(). Blocking call. Returns:
  //
  // OK - success.
  // TIMEOUT - on timeout.
  // INVALID_ARGUMENT - address or length is invalid.
  // PERMISSION_DENIED - partition is read only.
  // UNKNOWN - HAL error
  virtual StatusWithSize Write(Address address, span<const std::byte> data);

  // Check to see if chunk of flash partition is erased. Address and len need to
  // be aligned with FlashMemory. Returns:
  //
  // OK - success.
  // TIMEOUT - on timeout.
  // INVALID_ARGUMENT - address or length is invalid.
  // UNKNOWN - HAL error
  // TODO(hepler): Result<bool>
  virtual Status IsRegionErased(Address source_flash_address,
                                size_t length,
                                bool* is_erased);

  // Check if the entire partition is erased.
  // Returns: same as IsRegionErased().
  Status IsErased(bool* is_erased) {
    return IsRegionErased(0, this->size_bytes(), is_erased);
  }

  // Returns the address of the first byte of erased flash that has no more
  // written bytes to the end of the partition. If no erased bytes at end of
  // partition, then size_bytes of partition is returned.
  //
  // OK - success with number of bytes to end of written data.
  // Other - error code from flash read operation.
  StatusWithSize EndOfWrittenData();

  // Checks to see if the data appears to be erased. No reads or writes occur;
  // the FlashPartition simply compares the data to
  // flash_.erased_memory_content().
  bool AppearsErased(span<const std::byte> data) const;

  // Optionally overridden by derived classes. The reported sector size is space
  // available to users of FlashPartition. This reported size can be smaller or
  // larger than the sector size of the backing FlashMemory.
  //
  // Possible reasons for size to be different from the backing FlashMemory
  // could be due to space reserved in the sector for FlashPartition to store
  // metadata or due to logical FlashPartition sectors that combine several
  // FlashMemory sectors.
  virtual size_t sector_size_bytes() const {
    return flash_.sector_size_bytes();
  }

  // Optionally overridden by derived classes. The reported sector count is
  // sectors available to users of FlashPartition. This reported count can be
  // same or smaller than the given flash_sector_count of the backing
  // FlashMemory for the same region of flash.
  //
  // Possible reasons for count to be different from the backing FlashMemory
  // could be due to space reserved in the FlashPartition to store metadata or
  // due to logical FlashPartition sectors that combine several FlashMemory
  // sectors.
  virtual size_t sector_count() const { return flash_sector_count_; }

  size_t size_bytes() const { return sector_count() * sector_size_bytes(); }

  // Alignment required for write address and write size.
  size_t alignment_bytes() const { return alignment_bytes_; }

  // Convert a FlashMemory::Address to an MCU pointer, this can be used for
  // memory mapped reads. Return NULL if the memory is not memory mapped.
  std::byte* PartitionAddressToMcuAddress(Address address) const {
    return flash_.FlashAddressToMcuAddress(PartitionToFlashAddress(address));
  }

  // Converts an address from the partition address space to the flash address
  // space. If the partition reserves additional space in the sector, the flash
  // address space may not be contiguous, and this conversion accounts for that.
  virtual FlashMemory::Address PartitionToFlashAddress(Address address) const {
    return flash_.start_address() +
           (flash_start_sector_index_ - flash_.start_sector()) *
               flash_.sector_size_bytes() +
           address;
  }

  bool writable() const {
    return permission_ == PartitionPermission::kReadAndWrite;
  }

  constexpr std::byte erased_memory_content() const {
    return flash_.erased_memory_content();
  }

  uint32_t start_sector_index() const { return flash_start_sector_index_; }

 protected:
  Status CheckBounds(Address address, size_t len) const;

  FlashMemory& flash() const { return flash_; }

  FlashMemory& flash_;
  const uint32_t flash_sector_count_;

 private:
  const uint32_t flash_start_sector_index_;
  const uint32_t alignment_bytes_;
  const PartitionPermission permission_;
};

}  // namespace kvs
}  // namespace pw
