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

// This file defines classes for managing the in-flash format for KVS entires.
#pragma once

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string_view>

#include "pw_kvs/checksum.h"
#include "pw_kvs/flash_memory.h"
#include "pw_span/span.h"

namespace pw::kvs {

// EntryHeader represents a key-value entry as stored in flash.
class EntryHeader {
 public:
  EntryHeader() = default;

  // Creates a new EntryHeader for a valid (non-deleted) entry.
  static EntryHeader Valid(uint32_t magic,
                           ChecksumAlgorithm* algorithm,
                           std::string_view key,
                           span<const std::byte> value,
                           uint32_t key_version) {
    return EntryHeader(magic, algorithm, key, value, value.size(), key_version);
  }

  // Creates a new EntryHeader for a tombstone entry, which marks a deleted key.
  static EntryHeader Tombstone(uint32_t magic,
                               ChecksumAlgorithm* algorithm,
                               std::string_view key,
                               uint32_t key_version) {
    return EntryHeader(
        magic, algorithm, key, {}, kDeletedValueLength, key_version);
  }

  Status VerifyChecksum(ChecksumAlgorithm* algorithm,
                        std::string_view key,
                        span<const std::byte> value) const;

  Status VerifyChecksumInFlash(FlashPartition* partition,
                               FlashPartition::Address header_address,
                               ChecksumAlgorithm* algorithm) const;

  // Calculates the total size of the entry: header, key, and value.
  static constexpr size_t size(std::string_view key,
                               span<const std::byte> value) {
    return sizeof(EntryHeader) + key.size() + value.size();
  }

  size_t size() const {
    return sizeof(EntryHeader) + key_length() + value_length();
  }

  uint32_t magic() const { return magic_; }

  uint32_t checksum() const { return checksum_; }

  bool deleted() const {
    return (key_value_length_ >> kValueLengthShift) == kDeletedValueLength;
  }

  size_t key_length() const { return key_value_length_ & kKeyLengthMask; }
  void set_key_length(uint32_t key_length) {
    key_value_length_ = key_length | (~kKeyLengthMask & key_value_length_);
  }

  size_t value_length() const {
    return deleted() ? 0u : (key_value_length_ >> kValueLengthShift);
  }
  void set_value_length(uint32_t value_length) {
    key_value_length_ = (value_length << kValueLengthShift) |
                        (kKeyLengthMask & key_value_length_);
  }

  uint32_t key_version() const { return key_version_; }

 private:
  static constexpr uint32_t kNoChecksum = 0;
  static constexpr uint32_t kKeyLengthMask = 0b111111;
  static constexpr uint32_t kValueLengthShift = 8;
  static constexpr uint32_t kDeletedValueLength = 0xFFFFFF;

  EntryHeader(uint32_t magic,
              ChecksumAlgorithm* algorithm,
              std::string_view key,
              span<const std::byte> value,
              uint32_t value_length_field,
              uint32_t key_version);

  static constexpr size_t checked_data_offset() {
    return offsetof(EntryHeader, key_value_length_);
  }

  span<const std::byte> checksum_bytes() const {
    return as_bytes(span(&checksum_, 1));
  }

  void CalculateChecksum(ChecksumAlgorithm* algorithm,
                         std::string_view key,
                         span<const std::byte> value) const;

  uint32_t magic_;
  uint32_t checksum_;
  //  6 bits, 0: 5 - key - maximum 64 characters
  //  2 bits, 6: 7 - reserved
  // 24 bits, 8:31 - value - maximum 16MB
  uint32_t key_value_length_;
  uint32_t key_version_;
};

static_assert(sizeof(EntryHeader) == 16, "EntryHeader should have no padding");

}  // namespace pw::kvs
