// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVICES_BLOCK_DRIVERS_FTL_METRICS_H_
#define SRC_DEVICES_BLOCK_DRIVERS_FTL_METRICS_H_

#include <lib/inspect/cpp/inspect.h>
#include <lib/inspect/cpp/vmo/types.h>

#include <map>
#include <string>
#include <string_view>
#include <vector>

#include <fbl/span.h>

namespace ftl {

// Helper property wrapper that caches the value, in order to update
// the inspect property with the correct value, since properties are write only.
class RateProperty {
 public:
  explicit RateProperty(inspect::DoubleProperty property) : property_(std::move(property)) {}

  // Returns the accumulated rate as a weighted rate.
  double rate() const { return rate_.GetValue(); }

  // Updates the accumulated rate.
  void Add(int extra_accumulated) {
    rate_.accumulated += extra_accumulated;
    rate_.entries++;
    property_.Set(rate());
  }

 private:
  // Helper for keeping track and updating an accumulated rate.
  struct Rate {
    constexpr double GetValue() const {
      if (entries == 0) {
        return 0;
      }
      return static_cast<double>(accumulated) / entries;
    }

    int accumulated = 0;
    int entries = 0;
  };

  Rate rate_;
  inspect::DoubleProperty property_;
};

struct NestedNandOperationProperties {
  NestedNandOperationProperties(inspect::UintProperty count, inspect::DoubleProperty rate)
      : count(std::move(count)), rate(std::move(rate)) {}

  // Number of nand operations issued for a given type.
  inspect::UintProperty count;

  // Rate at which operations of this type are issued to the underlying device.
  RateProperty rate;
};

// For each type of block operation we keep the number of operations issued and the accumulated rate
// at which an operation is issued as a result of an incoming block operation into the FTL.
struct BlockOperationProperties {
  // Number of block operations of a given type that have been processed by the FTL.
  inspect::UintProperty count;

  // Operation stats per nand operation type for operation issued for this block operation type.
  NestedNandOperationProperties all;
  NestedNandOperationProperties page_read;
  NestedNandOperationProperties page_write;
  NestedNandOperationProperties block_erase;
};

// Encapsulates all existing metrics, and the property list names for each.
class Metrics {
 public:
  // Each of this functions returns the name of the property for a count or rate for the given pair.
  // Unknown combinations will return an empty string.
  static std::string GetMaxWearPropertyName() { return "max_wear"; }

  // Returns the list of expected properties in the hierarchy for each inspect metric type.
  template <typename InspectMetricType>
  static std::vector<std::string> GetPropertyNames();

  Metrics();

  inspect::UintProperty& max_wear() { return max_wear_; }

  BlockOperationProperties& read() { return read_; }
  BlockOperationProperties& write() { return write_; }
  BlockOperationProperties& trim() { return trim_; }
  BlockOperationProperties& flush() { return flush_; }

  zx::vmo DuplicateInspectVmo() const { return inspector_.DuplicateVmo(); }

 private:
  auto& GetRoot() { return root_; }

  inspect::Inspector inspector_;

  // Inspect root.
  inspect::Node root_;

  // Current maximum wear over all nand blocks.
  inspect::UintProperty max_wear_;

  // Properties for each block operation type.
  BlockOperationProperties read_;
  BlockOperationProperties write_;
  BlockOperationProperties flush_;
  BlockOperationProperties trim_;
};

}  // namespace ftl

#endif  // SRC_DEVICES_BLOCK_DRIVERS_FTL_METRICS_H_
