// 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 <algorithm>
#include <numeric>

#include "pw_containers/vector.h"
#include "pw_kvs/flash_memory.h"
#include "pw_kvs/key_value_store.h"
#include "pw_status/status.h"

#ifndef PW_KVS_RECORD_PARTITION_STATS
// PW_KVS_RECORD_PARTITION_STATS enables saving stats.
#define PW_KVS_RECORD_PARTITION_STATS 0
#endif  // PW_KVS_RECORD_PARTITION_STATS

namespace pw::kvs {

class FlashPartitionWithStats : public FlashPartition {
 public:
  // Save flash partition and KVS storage stats. Does not save if
  // sector_counters_ is zero.
  Status SaveStorageStats(const KeyValueStore& kvs, const char* label);

  using FlashPartition::Erase;

  Status Erase(Address address, size_t num_sectors) override;

  std::span<size_t> sector_erase_counters() {
    return std::span(sector_counters_.data(), sector_counters_.size());
  }

  size_t min_erase_count() const {
    if (sector_counters_.empty()) {
      return 0;
    }
    return *std::min_element(sector_counters_.begin(), sector_counters_.end());
  }

  size_t max_erase_count() const {
    if (sector_counters_.empty()) {
      return 0;
    }
    return *std::max_element(sector_counters_.begin(), sector_counters_.end());
  }

  size_t average_erase_count() const {
    return sector_counters_.empty()
               ? 0
               : total_erase_count() / sector_counters_.size();
  }

  size_t total_erase_count() const {
    return std::accumulate(
        sector_counters_.begin(), sector_counters_.end(), 0ul);
  }

  void ResetCounters() { sector_counters_.assign(sector_count(), 0); }

 protected:
  FlashPartitionWithStats(
      Vector<size_t>& sector_counters,
      FlashMemory* flash,
      uint32_t start_sector_index,
      uint32_t sector_count,
      uint32_t alignment_bytes = 0,  // Defaults to flash alignment
      PartitionPermission permission = PartitionPermission::kReadAndWrite)
      : FlashPartition(flash,
                       start_sector_index,
                       sector_count,
                       alignment_bytes,
                       permission),
        sector_counters_(sector_counters) {
    sector_counters_.assign(FlashPartition::sector_count(), 0);
  }

 private:
  Vector<size_t>& sector_counters_;
};

template <size_t kMaxSectors>
class FlashPartitionWithStatsBuffer : public FlashPartitionWithStats {
 public:
  FlashPartitionWithStatsBuffer(
      FlashMemory* flash,
      uint32_t start_sector_index,
      uint32_t sector_count,
      uint32_t alignment_bytes = 0,  // Defaults to flash alignment
      PartitionPermission permission = PartitionPermission::kReadAndWrite)
      : FlashPartitionWithStats(sector_counters_,
                                flash,
                                start_sector_index,
                                sector_count,
                                alignment_bytes,
                                permission) {}

  FlashPartitionWithStatsBuffer(FlashMemory* flash)
      : FlashPartitionWithStatsBuffer(
            flash, 0, flash->sector_count(), flash->alignment_bytes()) {}

 private:
  // If PW_KVS_RECORD_PARTITION_STATS is not set, use zero size vector which
  // will not save any stats.
  Vector<size_t, PW_KVS_RECORD_PARTITION_STATS ? kMaxSectors : 0>
      sector_counters_;
};

}  // namespace pw::kvs
