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

#include "pw_containers/vector.h"
#include "pw_kvs/flash_memory.h"
#include "pw_kvs/internal/hash.h"

namespace pw::kvs::internal {

constexpr size_t kEntryRedundancy = 2;

// Caches information about a key-value entry. Facilitates quickly finding
// entries without having to read flash.
class KeyDescriptor {
 public:
  enum State { kValid, kDeleted };

  KeyDescriptor(std::string_view key) : KeyDescriptor(key, 0, 0, kValid) {}
  KeyDescriptor(const KeyDescriptor& kd)
      : key_hash_(kd.key_hash_),
        transaction_id_(kd.transaction_id_),
        addresses_(kd.addresses_.begin(), kd.addresses_.end()),
        state_(kd.state_) {}

  KeyDescriptor& operator=(const KeyDescriptor& other) = default;

  uint32_t hash() const { return key_hash_; }
  uint32_t transaction_id() const { return transaction_id_; }

  // TODO: remove address() once all the use of it is gone.
  uint32_t address() const { return addresses_[0]; }

  Status UpdateAddress(FlashPartition::Address old_address,
                       FlashPartition::Address new_address) {
    for (auto& address : addresses()) {
      if (address == old_address) {
        address = new_address;
        return Status::OK;
      }
    }

    // Unable to find the address to update.
    return Status::INVALID_ARGUMENT;
  }

  Vector<FlashPartition::Address, kEntryRedundancy>& addresses() {
    return addresses_;
  }
  const Vector<FlashPartition::Address, kEntryRedundancy>& addresses() const {
    return addresses_;
  }

  State state() const { return state_; }

  // True if the KeyDesctiptor's transaction ID is newer than the specified ID.
  bool IsNewerThan(uint32_t other_transaction_id) const {
    // TODO: Consider handling rollover.
    return transaction_id() > other_transaction_id;
  }

  bool deleted() const { return state_ == kDeleted; }

 private:
  friend class Entry;

  KeyDescriptor(std::string_view key,
                uint32_t version,
                FlashPartition::Address address,
                State initial_state)
      : key_hash_(Hash(key)), transaction_id_(version), state_(initial_state) {
    addresses_.assign(1, address);
  }

  uint32_t key_hash_;
  uint32_t transaction_id_;

  static_assert(kEntryRedundancy > 0u);
  Vector<FlashPartition::Address, kEntryRedundancy> addresses_;

  // TODO: This information could be packed into the above fields to save RAM.
  State state_;
};

}  // namespace pw::kvs::internal
