// 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 "pw_blob_store/blob_store.h"

#include <algorithm>

#include "pw_assert/check.h"
#include "pw_blob_store/internal/metadata_format.h"
#include "pw_bytes/byte_builder.h"
#include "pw_bytes/span.h"
#include "pw_kvs/checksum.h"
#include "pw_kvs/flash_memory.h"
#include "pw_kvs/key_value_store.h"
#include "pw_log/log.h"
#include "pw_status/status.h"
#include "pw_status/status_with_size.h"
#include "pw_status/try.h"
#include "pw_stream/stream.h"

namespace pw::blob_store {

using internal::BlobMetadataHeader;
using internal::ChecksumValue;

Status BlobStore::Init() {
  if (initialized_) {
    return OkStatus();
  }

  PW_LOG_INFO("Init BlobStore");

  const size_t write_buffer_size_alignment =
      flash_write_size_bytes_ % partition_.alignment_bytes();
  PW_CHECK_UINT_EQ((write_buffer_size_alignment), 0);
  PW_CHECK_UINT_GE(write_buffer_.size_bytes(), flash_write_size_bytes_);
  PW_CHECK_UINT_GE(flash_write_size_bytes_, partition_.alignment_bytes());

  ResetChecksum();
  initialized_ = true;

  if (LoadMetadata().ok()) {
    PW_LOG_DEBUG("BlobStore init - Have valid blob of %u bytes",
                 static_cast<unsigned>(write_address_));
    return OkStatus();
  }

  // No saved blob, check for flash being erased.
  bool erased = false;
  if (partition_.IsErased(&erased).ok() && erased) {
    flash_erased_ = true;

    // Blob data is considered valid as soon as the flash is erased. Even though
    // there are 0 bytes written, they are valid.
    valid_data_ = true;
    PW_LOG_DEBUG("BlobStore init - is erased");
  } else {
    PW_LOG_DEBUG("BlobStore init - not erased");
  }
  return OkStatus();
}

Status BlobStore::LoadMetadata() {
  write_address_ = 0;
  flash_address_ = 0;
  file_name_length_ = 0;
  valid_data_ = false;

  BlobMetadataHeader metadata;
  metadata.reset();

  // For kVersion1 metadata versions, only the first member of
  // BlobMetadataHeaderV2 will be populated.
  if (!kvs_.Get(MetadataKey(), std::as_writable_bytes(std::span(&metadata, 1)))
           .ok()) {
    return Status::NotFound();
  }

  if (!ValidateChecksum(metadata.v1_metadata.data_size_bytes,
                        metadata.v1_metadata.checksum)
           .ok()) {
    PW_LOG_ERROR("BlobStore init - Invalidating blob with invalid checksum");
    Invalidate().IgnoreError();  // TODO(pwbug/387): Handle Status properly
    return Status::DataLoss();
  }

  write_address_ = metadata.v1_metadata.data_size_bytes;
  flash_address_ = metadata.v1_metadata.data_size_bytes;
  file_name_length_ = metadata.file_name_length;
  valid_data_ = true;

  return OkStatus();
}

size_t BlobStore::MaxDataSizeBytes() const { return partition_.size_bytes(); }

Status BlobStore::OpenWrite() {
  if (!initialized_) {
    return Status::FailedPrecondition();
  }

  // Writer can only be opened if there are no other writer or readers already
  // open.
  if (writer_open_ || readers_open_ != 0) {
    return Status::Unavailable();
  }

  PW_LOG_DEBUG("Blob writer open");

  writer_open_ = true;

  // Clear any existing contents.
  Invalidate().IgnoreError();  // TODO(pwbug/387): Handle Status properly

  return OkStatus();
}

StatusWithSize BlobStore::GetFileName(std::span<char> dest) const {
  if (!initialized_) {
    return StatusWithSize(Status::FailedPrecondition(), 0);
  }

  if (file_name_length_ == 0) {
    return StatusWithSize(Status::NotFound(), 0);
  }

  const size_t bytes_to_read =
      std::min(dest.size_bytes(), static_cast<size_t>(file_name_length_));

  Status status = bytes_to_read == file_name_length_
                      ? OkStatus()
                      : Status::ResourceExhausted();

  // Read file name from KVS.
  constexpr size_t kFileNameOffset = sizeof(BlobMetadataHeader);
  const StatusWithSize kvs_read_sws =
      kvs_.Get(MetadataKey(),
               std::as_writable_bytes(dest.first(bytes_to_read)),
               kFileNameOffset);
  status.Update(kvs_read_sws.status());
  return StatusWithSize(status, kvs_read_sws.size());
}

Status BlobStore::OpenRead() {
  if (!initialized_) {
    return Status::FailedPrecondition();
  }

  // Reader can only be opened if there is no writer open.
  if (writer_open_) {
    return Status::Unavailable();
  }

  if (!ValidToRead()) {
    PW_LOG_ERROR("Blob reader unable open without valid data");
    return Status::FailedPrecondition();
  }

  PW_LOG_DEBUG("Blob reader open");

  readers_open_++;
  return OkStatus();
}

Status BlobStore::CloseRead() {
  PW_CHECK_UINT_GT(readers_open_, 0);
  readers_open_--;
  PW_LOG_DEBUG("Blob reader close");
  return OkStatus();
}

Status BlobStore::Write(ConstByteSpan data) {
  if (!ValidToWrite()) {
    return Status::DataLoss();
  }
  if (data.size_bytes() == 0) {
    return OkStatus();
  }
  if (WriteBytesRemaining() == 0) {
    return Status::OutOfRange();
  }
  if (WriteBytesRemaining() < data.size_bytes()) {
    return Status::ResourceExhausted();
  }

  if (!EraseIfNeeded().ok()) {
    return Status::DataLoss();
  }

  // Write in (up to) 3 steps:
  // 1) Finish filling write buffer and if full write it to flash.
  // 2) Write as many whole block-sized chunks as the data has remaining
  //    after 1.
  // 3) Put any remaining bytes less than flash write size in the write buffer.

  // Step 1) If there is any data in the write buffer, finish filling write
  //         buffer and if full write it to flash.
  if (!WriteBufferEmpty()) {
    size_t bytes_in_buffer = WriteBufferBytesUsed();

    // Non-deferred writes only use the first flash_write_size_bytes_ of the
    // write buffer to buffer writes less than flash_write_size_bytes_.
    PW_CHECK_UINT_GT(flash_write_size_bytes_, bytes_in_buffer);

    // Not using WriteBufferBytesFree() because non-deferred writes (which
    // is this method) only use the first flash_write_size_bytes_ of the write
    // buffer.
    size_t buffer_remaining = flash_write_size_bytes_ - bytes_in_buffer;

    // Add bytes up to filling the flash write size.
    size_t add_bytes = std::min(buffer_remaining, data.size_bytes());
    std::memcpy(write_buffer_.data() + bytes_in_buffer, data.data(), add_bytes);
    write_address_ += add_bytes;
    bytes_in_buffer += add_bytes;
    data = data.subspan(add_bytes);

    if (bytes_in_buffer != flash_write_size_bytes_) {
      // If there was not enough bytes to finish filling the write buffer, there
      // should not be any bytes left.
      PW_DCHECK(data.size_bytes() == 0);
      return OkStatus();
    }

    // The write buffer is full, flush to flash.
    if (!CommitToFlash(write_buffer_).ok()) {
      return Status::DataLoss();
    }

    PW_DCHECK(WriteBufferEmpty());
  }

  // At this point, if data.size_bytes() > 0, the write buffer should be empty.
  // This invariant is checked as part of of steps 2 & 3.

  // Step 2) Write as many block-sized chunks as the data has remaining after
  //         step 1.
  while (data.size_bytes() >= flash_write_size_bytes_) {
    PW_DCHECK(WriteBufferEmpty());

    write_address_ += flash_write_size_bytes_;
    if (!CommitToFlash(data.first(flash_write_size_bytes_)).ok()) {
      return Status::DataLoss();
    }

    data = data.subspan(flash_write_size_bytes_);
  }

  // step 3) Put any remaining bytes to the buffer. Put the bytes starting at
  //         the begining of the buffer, since it must be empty if there are
  //         still bytes due to step 1 either cleaned out the buffer or didn't
  //         have any more data to write.
  if (data.size_bytes() > 0) {
    PW_DCHECK(WriteBufferEmpty());
    std::memcpy(write_buffer_.data(), data.data(), data.size_bytes());
    write_address_ += data.size_bytes();
  }

  return OkStatus();
}

Status BlobStore::AddToWriteBuffer(ConstByteSpan data) {
  if (!ValidToWrite()) {
    return Status::DataLoss();
  }
  if (WriteBytesRemaining() == 0) {
    return Status::OutOfRange();
  }
  if (WriteBufferBytesFree() < data.size_bytes()) {
    return Status::ResourceExhausted();
  }

  size_t bytes_in_buffer = WriteBufferBytesUsed();

  std::memcpy(
      write_buffer_.data() + bytes_in_buffer, data.data(), data.size_bytes());
  write_address_ += data.size_bytes();

  return OkStatus();
}

Status BlobStore::Flush() {
  if (!ValidToWrite()) {
    return Status::DataLoss();
  }
  if (WriteBufferBytesUsed() == 0) {
    return OkStatus();
  }
  // Don't need to check available space, AddToWriteBuffer() will not enqueue
  // more than can be written to flash.

  if (!EraseIfNeeded().ok()) {
    return Status::DataLoss();
  }

  ByteSpan data = std::span(write_buffer_.data(), WriteBufferBytesUsed());
  while (data.size_bytes() >= flash_write_size_bytes_) {
    if (!CommitToFlash(data.first(flash_write_size_bytes_)).ok()) {
      return Status::DataLoss();
    }

    data = data.subspan(flash_write_size_bytes_);
  }

  // Only a multiple of flash_write_size_bytes_ are written in the flush. Any
  // remainder is held until later for either a flush with
  // flash_write_size_bytes buffered or the writer is closed.
  if (!WriteBufferEmpty()) {
    PW_DCHECK_UINT_EQ(data.size_bytes(), WriteBufferBytesUsed());
    // For any leftover bytes less than the flash write size, move them to the
    // start of the bufer.
    std::memmove(write_buffer_.data(), data.data(), data.size_bytes());
  } else {
    PW_DCHECK_UINT_EQ(data.size_bytes(), 0);
  }

  return OkStatus();
}

Status BlobStore::FlushFinalPartialChunk() {
  size_t bytes_in_buffer = WriteBufferBytesUsed();

  PW_DCHECK_UINT_GT(bytes_in_buffer, 0);
  PW_DCHECK_UINT_LE(bytes_in_buffer, flash_write_size_bytes_);
  PW_DCHECK_UINT_LE(flash_write_size_bytes_, WriteBytesRemaining());

  PW_LOG_DEBUG(
      "  Remainder %u bytes in write buffer to zero-pad to flash write "
      "size and commit",
      static_cast<unsigned>(bytes_in_buffer));

  // Zero out the remainder of the buffer.
  auto zero_span = write_buffer_.subspan(bytes_in_buffer);
  std::memset(zero_span.data(),
              static_cast<int>(partition_.erased_memory_content()),
              zero_span.size_bytes());

  ConstByteSpan remaining_bytes = write_buffer_.first(flash_write_size_bytes_);
  return CommitToFlash(remaining_bytes, bytes_in_buffer);
}

Status BlobStore::CommitToFlash(ConstByteSpan source, size_t data_bytes) {
  if (data_bytes == 0) {
    data_bytes = source.size_bytes();
  }
  flash_erased_ = false;
  StatusWithSize result = partition_.Write(flash_address_, source);
  flash_address_ += data_bytes;
  if (checksum_algo_ != nullptr) {
    checksum_algo_->Update(source.first(data_bytes));
  }

  if (!result.status().ok()) {
    valid_data_ = false;
  }

  return result.status();
}

// Needs to be in .cc file since PW_CHECK doesn't like being in .h files.
size_t BlobStore::WriteBufferBytesUsed() const {
  PW_CHECK_UINT_GE(write_address_, flash_address_);
  return write_address_ - flash_address_;
}

// Needs to be in .cc file since PW_DCHECK doesn't like being in .h files.
size_t BlobStore::WriteBufferBytesFree() const {
  PW_DCHECK_UINT_GE(write_buffer_.size_bytes(), WriteBufferBytesUsed());
  size_t buffer_remaining = write_buffer_.size_bytes() - WriteBufferBytesUsed();
  return std::min(buffer_remaining, WriteBytesRemaining());
}

Status BlobStore::EraseIfNeeded() {
  if (flash_address_ == 0) {
    // Always just erase. Erase is smart enough to only erase if needed.
    return Erase();
  }
  return OkStatus();
}

StatusWithSize BlobStore::Read(size_t offset, ByteSpan dest) const {
  if (!ValidToRead()) {
    return StatusWithSize::FailedPrecondition();
  }
  if (offset >= ReadableDataBytes()) {
    return StatusWithSize::OutOfRange();
  }

  size_t available_bytes = ReadableDataBytes() - offset;
  size_t read_size = std::min(available_bytes, dest.size_bytes());

  return partition_.Read(offset, dest.first(read_size));
}

Result<ConstByteSpan> BlobStore::GetMemoryMappedBlob() const {
  if (!ValidToRead()) {
    return Status::FailedPrecondition();
  }

  std::byte* mcu_address = partition_.PartitionAddressToMcuAddress(0);
  if (mcu_address == nullptr) {
    return Status::Unimplemented();
  }
  return ConstByteSpan(mcu_address, ReadableDataBytes());
}

size_t BlobStore::ReadableDataBytes() const {
  // TODO: clean up state related to readable bytes.
  return flash_address_;
}

Status BlobStore::Erase() {
  // If already erased our work here is done.
  if (flash_erased_) {
    // The write buffer might already have bytes when this call happens, due to
    // a deferred write.
    PW_DCHECK_UINT_LE(write_address_, write_buffer_.size_bytes());
    PW_DCHECK_UINT_EQ(flash_address_, 0);

    // Erased blobs should be valid as soon as the flash is erased. Even though
    // there are 0 bytes written, they are valid.
    PW_DCHECK(valid_data_);
    return OkStatus();
  }

  // If any writes have been performed, reset the state.
  if (flash_address_ != 0) {
    Invalidate().IgnoreError();  // TODO(pwbug/387): Handle Status properly
  }

  Status status = partition_.Erase();

  if (status.ok()) {
    flash_erased_ = true;

    // Blob data is considered valid as soon as the flash is erased. Even though
    // there are 0 bytes written, they are valid.
    valid_data_ = true;
  }
  return status;
}

Status BlobStore::Invalidate() {
  // Blob data is considered if the flash is erased. Even though
  // there are 0 bytes written, they are valid.
  valid_data_ = flash_erased_;
  ResetChecksum();
  write_address_ = 0;
  flash_address_ = 0;
  file_name_length_ = 0;

  Status status = kvs_.Delete(MetadataKey());

  return (status.ok() || status.IsNotFound()) ? OkStatus() : Status::Internal();
}

Status BlobStore::ValidateChecksum(size_t blob_size_bytes,
                                   ChecksumValue expected) {
  if (blob_size_bytes == 0) {
    PW_LOG_INFO("Blob unable to validate checksum of an empty blob");
    return Status::Unavailable();
  }

  if (checksum_algo_ == nullptr) {
    if (expected != 0) {
      PW_LOG_ERROR(
          "Blob invalid to have a checkum value with no checksum algo");
      return Status::DataLoss();
    }

    return OkStatus();
  }

  PW_LOG_DEBUG("Validate checksum of 0x%08x in flash for blob of %u bytes",
               static_cast<unsigned>(expected),
               static_cast<unsigned>(blob_size_bytes));
  PW_TRY(CalculateChecksumFromFlash(blob_size_bytes));

  Status status = checksum_algo_->Verify(as_bytes(std::span(&expected, 1)));
  PW_LOG_DEBUG("  checksum verify of %s", status.str());

  return status;
}

Status BlobStore::CalculateChecksumFromFlash(size_t bytes_to_check) {
  if (checksum_algo_ == nullptr) {
    return OkStatus();
  }

  checksum_algo_->Reset();

  kvs::FlashPartition::Address address = 0;
  const kvs::FlashPartition::Address end = bytes_to_check;

  constexpr size_t kReadBufferSizeBytes = 32;
  std::array<std::byte, kReadBufferSizeBytes> buffer;
  while (address < end) {
    const size_t read_size = std::min(size_t(end - address), buffer.size());
    PW_TRY(partition_.Read(address, std::span(buffer).first(read_size)));

    checksum_algo_->Update(buffer.data(), read_size);
    address += read_size;
  }

  // Safe to ignore the return from Finish, checksum_algo_ keeps the state
  // information that it needs.
  checksum_algo_->Finish();
  return OkStatus();
}

Status BlobStore::BlobWriter::SetFileName(std::string_view file_name) {
  PW_DCHECK(open_);
  PW_DCHECK_NOTNULL(file_name.data());
  PW_DCHECK(store_.writer_open_);

  if (file_name.length() > MaxFileNameLength()) {
    return Status::ResourceExhausted();
  }

  // Stage the file name to the encode buffer, just past the BlobMetadataHeader
  // struct.
  constexpr size_t kFileNameOffset = sizeof(BlobMetadataHeader);
  const ByteSpan file_name_dest = metadata_buffer_.subspan(kFileNameOffset);
  std::memcpy(file_name_dest.data(), file_name.data(), file_name.length());

  store_.file_name_length_ = file_name.length();
  return OkStatus();
}

Status BlobStore::BlobWriter::Open() {
  PW_DCHECK(!open_);
  PW_DCHECK_UINT_GE(metadata_buffer_.size_bytes(),
                    sizeof(internal::BlobMetadataHeader));

  const Status status = store_.OpenWrite();
  if (status.ok()) {
    open_ = true;
  }
  return status;
}

// Validates and commits BlobStore metadata to KVS.
//
// 1. Finalize checksum calculation.
// 2. Check the calculated checksum against data actually committed to flash.
// 3. Build the metadata header into the metadata buffer, placing it before the
//    staged file name (if any).
// 4. Commit the metadata to KVS.
Status BlobStore::BlobWriter::WriteMetadata() {
  // Finalize the in-progress checksum, if any.
  ChecksumValue calculated_checksum = 0;
  if (store_.checksum_algo_ != nullptr) {
    ConstByteSpan checksum = store_.checksum_algo_->Finish();
    std::memcpy(&calculated_checksum,
                checksum.data(),
                std::min(checksum.size(), sizeof(ChecksumValue)));
  }

  // Check the in-memory checksum against the data that was actually committed
  // to flash.
  if (!store_.ValidateChecksum(store_.flash_address_, calculated_checksum)
           .ok()) {
    PW_CHECK_OK(store_.Invalidate());
    return Status::DataLoss();
  }

  // Encode the metadata header. This follows the latest struct behind
  // BlobMetadataHeader. Currently, the order is as follows:
  // - Encode checksum.
  // - Encode stored data size.
  // - Encode version magic.
  // - Encode file name size.
  // - File name, if present, is already staged at the end.
  //
  // Open() guarantees the metadata buffer is large enough to fit the metadata
  // header.
  ByteBuilder metadata_builder(metadata_buffer_);
  metadata_builder.PutUint32(calculated_checksum);
  metadata_builder.PutUint32(store_.flash_address_);
  metadata_builder.PutUint32(internal::MetadataVersion::kLatest);
  metadata_builder.PutUint8(store_.file_name_length_);
  PW_DCHECK_INT_EQ(metadata_builder.size(), sizeof(BlobMetadataHeader));
  PW_DCHECK_OK(metadata_builder.status());

  // If a filename was provided, it is already written to the correct location
  // in the buffer. When the file name was set, the metadata buffer was verified
  // to fit the requested name in addition to the metadata header. If it doesn't
  // fit now, something's very wrong.
  const size_t bytes_to_write =
      metadata_builder.size() + store_.file_name_length_;
  PW_DCHECK(metadata_buffer_.size_bytes() >= bytes_to_write);

  // Do final commit to KVS.
  return store_.kvs_.Put(store_.MetadataKey(),
                         metadata_buffer_.first(bytes_to_write));
}

Status BlobStore::BlobWriter::Close() {
  PW_DCHECK(open_);
  open_ = false;

  // This is a lambda so the BlobWriter will be unconditionally closed even if
  // the final flash commits fail. This lambda may early return to Close() if
  // errors are encountered, but Close() will not return without updating both
  // the BlobWriter and BlobStore such that neither are open for writes
  // anymore.
  auto do_close_write = [&]() -> Status {
    // If not valid to write, there was data loss and the close will result in a
    // not valid blob. Don't need to flush any write buffered bytes.
    if (!store_.ValidToWrite()) {
      return Status::DataLoss();
    }

    if (store_.write_address_ == 0) {
      return OkStatus();
    }

    PW_LOG_DEBUG(
        "Blob writer close of %u byte blob, with %u bytes still in write "
        "buffer",
        static_cast<unsigned>(store_.write_address_),
        static_cast<unsigned>(store_.WriteBufferBytesUsed()));

    // Do a Flush of any flash_write_size_bytes_ sized chunks so any remaining
    // bytes in the write buffer are less than flash_write_size_bytes_.
    PW_TRY(store_.Flush());

    // If any bytes remain in buffer it is because it is a chunk less than
    // flash_write_size_bytes_. Pad the chunk to flash_write_size_bytes_ and
    // write it to flash.
    if (!store_.WriteBufferEmpty()) {
      PW_TRY(store_.FlushFinalPartialChunk());
    }
    PW_DCHECK(store_.WriteBufferEmpty());

    if (!WriteMetadata().ok()) {
      return Status::DataLoss();
    }

    return OkStatus();
  };

  const Status status = do_close_write();
  store_.writer_open_ = false;

  if (!status.ok()) {
    store_.valid_data_ = false;
    return Status::DataLoss();
  }
  return OkStatus();
}

}  // namespace pw::blob_store
