// Copyright 2019 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 LIB_INSPECT_INSPECT_H_
#define LIB_INSPECT_INSPECT_H_

#include <lib/component/cpp/exposed_object.h>
#include <lib/fit/variant.h>
#include <lib/inspect-vmo/inspect.h>
#include <zircon/types.h>

#include <string>

#include "lib/inspect-vmo/block.h"
#include "lib/inspect-vmo/types.h"

namespace inspect {

class Object;

namespace internal {

// Factories for creating metrics.
template <typename T>
component::Metric MakeMetric(T value);

// Factory to create an IntMetric.
template <>
component::Metric MakeMetric<int64_t>(int64_t value);

// Factory to create a UIntMetric.
template <>
component::Metric MakeMetric<uint64_t>(uint64_t value);

// Factory to create a DoubleMetric.
template <>
component::Metric MakeMetric<double>(double value);

// Template for functions that remove a named entity of a given type from an
// object.
template <typename EntityType>
void RemoveEntity(::component::Object* object, const std::string& name);

// Removal function for Metric.
template <>
void RemoveEntity<component::Metric>(::component::Object* object,
                                     const std::string& name);

// Removal function for Property.
template <>
void RemoveEntity<component::Property>(::component::Object* object,
                                       const std::string& name);

// Wrapper class for entity types supported by the Inspect API.
// This class implements RAII behavior for created Inspect entities,
// including removing values from the tree when the owner goes out of scope.
template <typename EntityType>
class EntityWrapper final {
 public:
  EntityWrapper(std::string name, std::shared_ptr<::component::Object> obj)
      : name_(std::move(name)), parent_obj_(std::move(obj)) {}

  ~EntityWrapper() {
    // Remove the entity from its parent if it has a parent.
    if (parent_obj_) {
      RemoveEntity<EntityType>(parent_obj_.get(), name_);
    }
  }

  // Allow moving, disallow copying.
  EntityWrapper(const EntityWrapper& other) = delete;
  EntityWrapper(EntityWrapper&& other) = default;
  EntityWrapper& operator=(const EntityWrapper& other) = delete;
  EntityWrapper& operator=(EntityWrapper&& other) {
    // Remove the entity from its parent before moving values over.
    if (parent_obj_) {
      RemoveEntity<EntityType>(parent_obj_.get(), name_);
    }
    name_ = std::move(other.name_);
    parent_obj_ = std::move(other.parent_obj_);
    return *this;
  }

  explicit operator bool() const { return parent_obj_.get() != nullptr; }

  // Get the name for this entity.
  const std::string& name() const { return name_; }

  ::component::Object* ParentObject() { return parent_obj_.get(); }

 private:
  explicit EntityWrapper(std::string name) : name_(std::move(name)) {}

  std::string name_;
  std::shared_ptr<::component::Object> parent_obj_;
};

// Structure containing internal data for a |Tree|.
struct TreeState;

}  // namespace internal

// Template for metrics that are concretely stored in memory (as opposed to
// LazyMetrics, which are dynamically created when needed). StaticMetrics
// can be set, added to, and subtracted from.
template <typename T, typename VmoType>
class StaticMetric final {
 public:
  // Create a default numeric metric.
  // Operations on the metric will have no effect.
  StaticMetric() = default;

  // Set the value of this numeric metric to the given value.
  void Set(T value) {
    if (entity_.index() == kEntityWrapperVariant) {
      auto& entity = entity_.template get<kEntityWrapperVariant>();
      entity.ParentObject()->SetMetric(entity.name(),
                                       internal::MakeMetric<T>(value));
    } else if (entity_.index() == kVmoVariant) {
      entity_.template get<kVmoVariant>().Set(value);
    }
  }

  // Add the given value to the value of this numeric metric.
  void Add(T value) {
    if (entity_.index() == kEntityWrapperVariant) {
      auto& entity = entity_.template get<kEntityWrapperVariant>();
      entity.ParentObject()->AddMetric(entity.name(), value);
    } else if (entity_.index() == kVmoVariant) {
      entity_.template get<kVmoVariant>().Add(value);
    }
  }

  // Subtract the given value from the value of this numeric metric.
  void Subtract(T value) {
    if (entity_.index() == kEntityWrapperVariant) {
      auto& entity = entity_.template get<kEntityWrapperVariant>();
      entity.ParentObject()->SubMetric(entity.name(), value);
    } else if (entity_.index() == kVmoVariant) {
      entity_.template get<kVmoVariant>().Subtract(value);
    }
  }

 private:
  friend class ::inspect::Object;

  // Index of the entity wrapper variant of the metric.
  static const int kEntityWrapperVariant = 1;
  // Index of the VMO variant of the metric.
  static const int kVmoVariant = 2;

  // Internal constructor wrapping an entity in memory.
  explicit StaticMetric(internal::EntityWrapper<component::Metric> entity) {
    entity_.template emplace<kEntityWrapperVariant>(std::move(entity));
  }

  // Internal constructor wrapping a VMO type.
  explicit StaticMetric(VmoType entity) {
    entity_.template emplace<kVmoVariant>(std::move(entity));
  }

  fit::internal::variant<fit::internal::monostate,
                         internal::EntityWrapper<component::Metric>, VmoType>
      entity_;
};

template <typename T, typename VmoType>
class ArrayMetric final {
 public:
  // Create a default numeric array metric.
  // Operations on the metric will have no effect.
  ArrayMetric() = default;

  // Set the value of the given array index.
  void Set(size_t index, T value) { vmo_metric_.Set(index, value); }

  // Add the given value to given array index.
  void Add(size_t index, T value) { vmo_metric_.Add(index, value); }

  // Subtract the given value to the given array index.
  void Subtract(size_t index, T value) { vmo_metric_.Subtract(index, value); }

 private:
  friend class ::inspect::Object;

  // Internal constructor wrapping a VMO type.
  explicit ArrayMetric(VmoType vmo_metric)
      : vmo_metric_(std::move(vmo_metric)) {}

  VmoType vmo_metric_;
};

// Metric wrapping a signed integer.
using IntMetric = StaticMetric<int64_t, vmo::IntMetric>;

// Metric wrapping an unsigned integer.
using UIntMetric = StaticMetric<uint64_t, vmo::UintMetric>;

// Metric wrapping a double floating point number.
using DoubleMetric = StaticMetric<double, vmo::DoubleMetric>;

// Array of signed integers.
using IntArray = ArrayMetric<int64_t, vmo::IntArray>;

// Array of unsigned integers.
using UIntArray = ArrayMetric<uint64_t, vmo::UintArray>;

// Array of double floating point numbers.
using DoubleArray = ArrayMetric<double, vmo::DoubleArray>;

template <typename T, typename VmoType>
class HistogramMetric final {
 public:
  // Create a default histogram.
  // Operations on the metric will have no effect.
  HistogramMetric() = default;

  // Insert the given value once to the correct bucket of the histogram.
  void Insert(T value) { Insert(value, 1); }

  // Insert the given value |count| times to the correct bucket of the
  // histogram.
  void Insert(T value, T count) { histogram_.Insert(value, count); }

 private:
  friend class ::inspect::Object;

  // Internal constructor wrapping a VMO type.
  HistogramMetric(VmoType histogram) : histogram_(std::move(histogram)) {}

  VmoType histogram_;
};

// Linear histogram of integers.
using LinearIntHistogramMetric =
    HistogramMetric<int64_t, vmo::LinearIntHistogram>;

// Linear histogram of unsigned integers.
using LinearUIntHistogramMetric =
    HistogramMetric<uint64_t, vmo::LinearUintHistogram>;

// Linear histogram of doubles.
using LinearDoubleHistogramMetric =
    HistogramMetric<double, vmo::LinearDoubleHistogram>;

// Exponential histogram of integers.
using ExponentialIntHistogramMetric =
    HistogramMetric<int64_t, vmo::ExponentialIntHistogram>;

// Exponential histogram of unsigned integers.
using ExponentialUIntHistogramMetric =
    HistogramMetric<uint64_t, vmo::ExponentialUintHistogram>;

// Exponential histogram of doubles.
using ExponentialDoubleHistogramMetric =
    HistogramMetric<double, vmo::ExponentialDoubleHistogram>;

// Metric with value determined by evaluating a callback.
class LazyMetric final {
 public:
  // Construct a default metric.
  // Operations on the metric will have no effect.
  LazyMetric();

  LazyMetric(LazyMetric&&) = default;
  LazyMetric(const LazyMetric&) = delete;

  LazyMetric& operator=(LazyMetric&&) = default;
  LazyMetric& operator=(const LazyMetric&) = delete;

  // Set the callback used to return the value of the metric.
  void Set(::component::Metric::ValueCallback callback);

 private:
  friend class ::inspect::Object;
  // Internal constructor setting an actual value on an Object.
  explicit LazyMetric(internal::EntityWrapper<component::Metric> entity);

  fit::optional<internal::EntityWrapper<component::Metric>> entity_;
};

// The value of a metric, currently an alias for component::Metric.
using MetricValue = ::component::Metric;

using MetricCallback = ::component::Metric::ValueCallback;

// Property with value given by a string.
class StringProperty final {
 public:
  // Construct a default property.
  // Operations on the property will have no effect.
  StringProperty();

  // Set the string value of the property.
  void Set(std::string value);

 private:
  friend class ::inspect::Object;

  // Index of the entity wrapper variant of the property.
  static const int kEntityWrapperVariant = 1;
  // Index of the VMO variant of the property.
  static const int kVmoVariant = 2;

  // Internal constructor wrapping an entity in memory.
  explicit StringProperty(internal::EntityWrapper<component::Property> entity);

  // Internal constructor wrapping a VMO entity.
  explicit StringProperty(vmo::Property entity);

  fit::internal::variant<fit::internal::monostate,
                         internal::EntityWrapper<component::Property>,
                         vmo::Property>
      entity_;
};

// Property with value given by an array of bytes.
class ByteVectorProperty final {
 public:
  // Construct a default property.
  // Operations on the property will have no effect.
  ByteVectorProperty();

  // Set the vector value of the property.
  void Set(::component::Property::ByteVector value);

 private:
  friend class ::inspect::Object;

  // Index of the entity wrapper variant of the property.
  static const int kEntityWrapperVariant = 1;
  // Index of the VMO variant of the property.
  static const int kVmoVariant = 2;

  // Internal constructor wrapping an entity in memory.
  explicit ByteVectorProperty(
      internal::EntityWrapper<component::Property> entity);

  // Internal constructor wrapping a VMO entity.
  explicit ByteVectorProperty(vmo::Property entity);

  fit::internal::variant<fit::internal::monostate,
                         internal::EntityWrapper<component::Property>,
                         vmo::Property>
      entity_;
};

// Callback type for string values.
using StringValueCallback = ::component::Property::StringValueCallback;

// Property with string value determined by evaluating a callback.
class LazyStringProperty final {
 public:
  // Construct a default property.
  // Operations on the property will have no effect.
  LazyStringProperty();

  LazyStringProperty(LazyStringProperty&&) = default;
  LazyStringProperty(const LazyStringProperty&) = delete;

  LazyStringProperty& operator=(LazyStringProperty&&) = default;
  LazyStringProperty& operator=(const LazyStringProperty&) = delete;

  // Set the callback that generates the value of the property.
  void Set(StringValueCallback callback);

 private:
  friend class ::inspect::Object;

  // Internal constructor setting an actual value on an Object.
  explicit LazyStringProperty(
      internal::EntityWrapper<component::Property> entity);

  fit::optional<internal::EntityWrapper<component::Property>> entity_;
};

// Callback type for vector values.
using VectorValueCallback = ::component::Property::VectorValueCallback;

// Property with byte vector value determined by evaluating a callback.
class LazyByteVectorProperty final {
 public:
  // Construct a default property.
  // Operations on the property will have no effect.
  LazyByteVectorProperty();

  LazyByteVectorProperty(LazyByteVectorProperty&&) = default;
  LazyByteVectorProperty(const LazyByteVectorProperty&) = delete;

  LazyByteVectorProperty& operator=(LazyByteVectorProperty&&) = default;
  LazyByteVectorProperty& operator=(const LazyByteVectorProperty&) = delete;

  // Set the callback that generates the value of the property.
  void Set(VectorValueCallback callback);

 private:
  friend class ::inspect::Object;

  // Internal constructor setting an actual value on an Object.
  explicit LazyByteVectorProperty(
      internal::EntityWrapper<component::Property> entity);

  fit::optional<internal::EntityWrapper<component::Property>> entity_;
};

// Value of vector types, currently an alias for
// component::Property::ByteVector.
using VectorValue = component::Property::ByteVector;

using ChildrenCallbackFunction = ::component::Object::ChildrenCallback;

// ChildrenCallback is an RAII wrapper around a callback attached to an
// Object that provides additional children dynamically.
class ChildrenCallback final {
 public:
  // Construct a default children callback.
  ChildrenCallback();
  ~ChildrenCallback();

  // Set the callback function for the parent object to the given value.
  void Set(ChildrenCallbackFunction callback);

  // Allow moving, disallow copying.
  ChildrenCallback(ChildrenCallback& other) = delete;
  ChildrenCallback& operator=(ChildrenCallback& other) = delete;
  ChildrenCallback(ChildrenCallback&& other) = default;
  ChildrenCallback& operator=(ChildrenCallback&& other);

 private:
  friend class ::inspect::Object;

  // Internal constructor setting an actual children callback on an object.
  ChildrenCallback(std::shared_ptr<::component::Object> object);

  std::shared_ptr<::component::Object> parent_obj_;
};

// An object under which properties, metrics, and other objects may be nested.
class Object final {
 public:
  // Default construct an empty Object that does nothing until assigned to.
  Object() = default;

  // Construct an object with an explicit name.
  // DEPRECATED: Use Inspector and CreateTree instead of constructing objects
  // directly.
  explicit Object(std::string name);

  // Construct an Object wrapping the given ObjectDir.
  explicit Object(component::ObjectDir object_dir);

  // Construct an Object wrapping the given VMO Object.
  explicit Object(vmo::Object object);

  ~Object() = default;

  // Output the contents of this object as a FIDL struct.
  // For Objects stored in a VMO, this method returns a default value.
  fuchsia::inspect::Object object() const;

  // Get an ObjectDir wrapping this Object's state.
  // For Objects stored in a VMO, this method returns a default value.
  component::ObjectDir object_dir() const;

  // Output the list of this object's children as a FIDL-compatible vector.
  // For Objects stored in a VMO, this method returns a default value.
  ::component::Object::StringOutputVector children() const;

  // Allow moving, disallow copying.
  Object(const Object& other) = delete;
  Object(Object&& other) = default;
  Object& operator=(const Object& other) = delete;
  Object& operator=(Object&& other) = default;

  // Create a new |Object| with the given name that is a child of this object.
  [[nodiscard]] Object CreateChild(std::string name);

  // Create a new |IntMetric| with the given name that is a child of this
  // object.
  [[nodiscard]] IntMetric CreateIntMetric(std::string name, int64_t value);

  // Create a new |UIntMetric| with the given name that is a child of this
  // object.
  [[nodiscard]] UIntMetric CreateUIntMetric(std::string name, uint64_t value);

  // Create a new |DoubleMetric| with the given name that is a child of this
  // object.
  [[nodiscard]] DoubleMetric CreateDoubleMetric(std::string name, double value);

  // Create a new |IntArray| with the given name that is a child of this
  // object.
  [[nodiscard]] IntArray CreateIntArray(std::string name, size_t slots);

  // Create a new |UIntArray| with the given name that is a child of this
  // object.
  [[nodiscard]] UIntArray CreateUIntArray(std::string name, size_t slots);

  // Create a new |DoubleArray| with the given name that is a child of this
  // object.
  [[nodiscard]] DoubleArray CreateDoubleArray(std::string name, size_t slots);

  // Create a new |LinearIntHistogramMetric| with the given name that is a child
  // of this object.
  [[nodiscard]] LinearIntHistogramMetric CreateLinearIntHistogramMetric(
      std::string name, int64_t floor, int64_t step_size, size_t buckets);

  // Create a new |LinearUIntHistogramMetric| with the given name that is a
  // child of this object.
  [[nodiscard]] LinearUIntHistogramMetric CreateLinearUIntHistogramMetric(
      std::string name, uint64_t floor, uint64_t step_size, size_t buckets);

  // Create a new |LinearDoubleHistogramMetric| with the given name that is a
  // child of this object.
  [[nodiscard]] LinearDoubleHistogramMetric CreateLinearDoubleHistogramMetric(
      std::string name, double floor, double step_size, size_t buckets);

  // Create a new |ExponentialIntHistogramMetric| with the given name that is a
  // child of this object.
  [[nodiscard]] ExponentialIntHistogramMetric
  CreateExponentialIntHistogramMetric(std::string name, int64_t floor,
                                      int64_t initial_step,
                                      int64_t step_multiplier, size_t buckets);

  // Create a new |ExponentialIntHistogramMetric| with the given name that is a
  // child of this object.
  [[nodiscard]] ExponentialUIntHistogramMetric
  CreateExponentialUIntHistogramMetric(std::string name, uint64_t floor,
                                       uint64_t initial_step,
                                       uint64_t step_multiplier,
                                       size_t buckets);

  // Create a new |ExponentialDoubleHistogramMetric| with the given name that is
  // a child of this object.
  [[nodiscard]] ExponentialDoubleHistogramMetric
  CreateExponentialDoubleHistogramMetric(std::string name, double floor,
                                         double initial_step,
                                         double step_multiplier,
                                         size_t buckets);

  // Create a new |StringProperty| with the given name that is a child of this
  // object.
  [[nodiscard]] StringProperty CreateStringProperty(std::string name,
                                                    std::string value);

  // Create a new |ByteVectorProperty| with the given name that is a child of
  // this object.
  // For Objects stored in a VMO, this method has no effect.
  [[nodiscard]] ByteVectorProperty CreateByteVectorProperty(
      std::string name, component::Property::ByteVector value);

  // Create a new |StringCallbackProperty| with the given name that is a child
  // of this object.
  // For Objects stored in a VMO, this method has no effect.
  [[nodiscard]] LazyStringProperty CreateLazyStringProperty(
      std::string name, component::Property::StringValueCallback callback);

  // Create a new |VectorCallbackProperty| with the given name that is a child
  // of this object.
  // For Objects stored in a VMO, this method has no effect.
  [[nodiscard]] LazyByteVectorProperty CreateLazyByteVectorProperty(
      std::string name, component::Property::VectorValueCallback callback);

  // Create a new |LazyMetric| with the given name that is a child of this
  // object.
  // For Objects stored in a VMO, this method has no effect.
  [[nodiscard]] LazyMetric CreateLazyMetric(std::string name,
                                            component::Metric::ValueCallback);

  // Create a new |ChildrenCallback| that dynamically adds children to the
  // object at runtime.
  // For Objects stored in a VMO, this method has no effect.
  [[nodiscard]] ChildrenCallback CreateChildrenCallback(
      ChildrenCallbackFunction callback);

 private:
  static const int kComponentVariant = 1;
  static const int kVmoVariant = 2;

  // Construct an Object facade in front of an ExposedObject.
  explicit Object(component::ExposedObject object);

  [[nodiscard]] IntArray CreateIntArray(std::string name, size_t slots,
                                        vmo::ArrayFormat format);
  [[nodiscard]] UIntArray CreateUIntArray(std::string name, size_t slots,
                                          vmo::ArrayFormat format);
  [[nodiscard]] DoubleArray CreateDoubleArray(std::string name, size_t slots,
                                              vmo::ArrayFormat format);

  fit::internal::variant<fit::internal::monostate, component::ExposedObject,
                         vmo::Object>
      object_;
};

// Settings to configure a specific Tree.
struct TreeSettings {
  // The initial size of the created VMO.
  size_t initial_size;
  // The maximum size of the created VMO.
  size_t maximum_size;
};

// A |Tree| of inspect objects available in a VMO.
class Tree final {
 public:
  Tree() = default;
  ~Tree();

  // Allow moving, disallow copying.
  Tree(Tree&& other) = default;
  Tree(const Tree& other) = delete;
  Tree& operator=(Tree&& other) = default;
  Tree& operator=(const Tree& other) = delete;

  // Get the root object for this Tree.
  Object& GetRoot() const;

  // Get a reference to the VMO backing this tree.
  const zx::vmo& GetVmo() const;

 private:
  friend class Inspector;

  // Construct a new Tree with the given state;
  Tree(std::unique_ptr<internal::TreeState>);

  // The state for the tree, shared between copies.
  std::unique_ptr<internal::TreeState> state_;
};

// The entry point into the Inspection API.
//
// An Inspector supports creating trees of objects to expose over VMOs.
class Inspector {
 public:
  Inspector() = default;

  // Construct a new tree with the given name and default settings.
  Tree CreateTree(std::string name);

  // Construct a new tree with the given name and settings.
  Tree CreateTree(std::string name, TreeSettings settings);
};

// Generate a unique name with the given prefix.
std::string UniqueName(const std::string& prefix);

}  // namespace inspect

#endif  // LIB_INSPECT_INSPECT_H_
