// Copyright 2023 Google LLC
//
// 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.

#ifndef MPACT_SIM_GENERIC_COUNTERS_H_
#define MPACT_SIM_GENERIC_COUNTERS_H_

#include <cstdint>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/types/variant.h"
#include "mpact/sim/generic/counters_base.h"
#include "mpact/sim/generic/variant_helper.h"
#include "mpact/sim/proto/component_data.pb.h"

// This file defines the user facing classes for the simulator statistics
// instrumentation infrastructure. Base classes are located in counters_base.h.
// It is intended that instances of the counter classes are used to accumulate
// results locally in software components, whereas the CounterBaseInterface
// class (defined in counters_base.h) can be used to access the results in a
// type independent way, suitable for access through a registry to collect and
// process the results at the end of a simulation.
//
// While CounterBaseInterface is type agnostic, the derived classes are
// templated on the input and output data type. The output data type of a
// counter is restricted to the set of types in the absl::variant type aliased
// as CounterValue.
//
// This file defines three classes. The first is CounterValueOutputBase<T>
// which is templated, but only valid for the types in the CounterValue
// variant (see below and in counters_base.h). This class inherits from
// CounterBaseInterface and implements some of the common functionality.
//
// The second class is SimpleCounter<T>, where T is in the variant but also an
// arithmetic type (in the case a non-arithmetic type gets added to the variant
// in the future). It supports setting, incrementing and decrementing of the
// counter value.
//
// The third type is FunctionCounter<In, Out> where In and Out are the types in
// the SetValue interface (no Increment or Decrement methods are supported) and
// the CounterValueOutputBase<> class respectively. The FunctionCounter applies
// a user supplied function or functor to the input value to optionally produce
// an output value. The function/functor is of type
// std::function<bool(const In&, Out *)>, and returns true if the output value
// was updated, false otherwise.

namespace mpact {
namespace sim {
namespace generic {

// The generic value of a counter is an absl::variant containing a set of
// anticipated frequently used types that aliased to CounterValue. It is
// defined in counters_base.h as:
//   using CounterValue = absl::variant<uint64, int64, double>;
//
// Templated output base class. The template argument must be one of the types
// in the CounterValue variant, if not, the static_assert will generate an
// error. The CounterValueOutputBase<> class implements all the pure virtual
// methods from CounterBaseInterface except for ToString(). The implementations
// are declared final to allow the compiler to de-virtualize calls to these
// methods made in instances of derived classes.
template <typename T>
class CounterValueOutputBase : public CounterBaseInterface {
  // Static check to signal error when an illegal type is used.
  static_assert(mpact::sim::generic::IsMemberOfVariant<CounterValue, T>::value,
                "Template argument type is not in CounterValue variant");

 public:
  // Constructors and destructor.
  // The default constructor does not initialize the counter. A separate call
  // to Initialize(..) is required before it can be added to a component.
  CounterValueOutputBase() : is_enabled_(false), is_initialized_(false) {}
  // Constructs and initializes the counter.
  CounterValueOutputBase(std::string name, const T initial)
      : name_(std::move(name)),
        about_(),
        is_enabled_(true),
        is_initialized_(true),
        value_(std::move(initial)) {}
  ~CounterValueOutputBase() override = default;

  // Method to add an object that implements the CounterInputSetInterface<T>
  // to be added a a listener, which means that its SetValue() method will be
  // called whenever value of the counter is updated. The caller retains
  // ownership of the listener.
  void AddListener(CounterValueSetInterface<T> *listener) {
    listeners_.push_back(listener);
  }
  // Implementation of the pure virtual method from CounterBaseInterface to
  // return the value as a variant. Notice, this method is declared as final to
  // enable the compiler to "de-virtualize" the method and improve its
  // performance when called in certain circumstances.
  CounterValue GetCounterValue() const final { return CounterValue(value_); }

  // Typed getter for the counter value.
  T GetValue() const { return value_; }

  // Method for exporting the counter to proto message. Calls ExportValue
  // for the type specific export, as each different type needs to set
  // a different field in the proto message.
  absl::Status Export(
      mpact::sim::proto::ComponentValueEntry *entry) const override {
    if (entry == nullptr) return absl::InvalidArgumentError("Entry is null");
    entry->set_name(GetName());
    if (!GetAbout().empty()) {
      entry->set_about(GetAbout());
    }
    ExportValue(entry);
    return absl::OkStatus();
  }

  // Must be called before being added to a component if the counter was
  // created using the default constructor.
  void Initialize(std::string name, const T initial) {
    name_ = std::move(name);
    value_ = std::move(initial);
    is_initialized_ = true;
    is_enabled_ = true;
  }

  // Implementation of pure virtual methods inherited from CounterBaseInterface
  // that act as accessors. Keeping the names in PascalCase since they implement
  // an inherited interface.
  std::string GetName() const final { return name_; }
  std::string GetAbout() const final { return about_; }
  void SetAbout(std::string about) final { about_ = std::move(about); }
  bool IsEnabled() const final { return is_enabled_; }
  void SetIsEnabled(bool is_enabled) final { is_enabled_ = is_enabled; }
  bool IsInitialized() const final { return is_initialized_; }

 protected:
  // The setter for the counter value used by derived classes. Calls the set
  // of registered listener objects with the new value.
  void UpdateValue(T value) {
    value_ = std::move(value);
    for (auto *listener : listeners_) {
      listener->SetValue(value_);
    }
  }

 private:
  // This method exports the typed value of the counter to the appropriate
  // field in the proto message. Note, this method is defined at the bottom of
  // this file.
  void ExportValue(mpact::sim::proto::ComponentValueEntry *entry) const;
  // Objects pointed to are owned elsewhere. Their lifetimes must exceed the
  // lifetime of the counter, or at least beyond the last call to UpdateValue.
  std::vector<CounterValueSetInterface<T> *> listeners_;
  std::string name_;
  std::string about_;
  bool is_enabled_;
  bool is_initialized_;
  T value_;
};

// A simple arithmetic counter class that supports increment and decrement. Only
// enabled for arithmetic types. This class has multiple inheritance from both
// the input interface and the output base class. The input interface is pure
// virtual, so there is no multiple implementation inheritance. There is also
// no possibility of a diamond pattern. The input interface inheritance is also
// necessary should instances of this class be used as a listener to another
// counter.
template <typename T>
class SimpleCounter : public CounterValueOutputBase<T>,
                      public CounterValueIncrementInterface<T> {
  // Static checks on the template argument type. The IsMemberOfVariant<T> check
  // is repeated to simplify error messages. If it is omitted and T is not in
  // the counter type, additional error messages may be generated for each of
  // the methods inherited from CounterBaseInterface and
  // CounterValueOutputInterface.
  static_assert(mpact::sim::generic::IsMemberOfVariant<CounterValue, T>::value,
                "Template argument type T is not in CounterValue variant.");
  static_assert(std::is_arithmetic<T>::value,
                "Template argument type T must be arithmetic.");

 public:
  // Since this class derives from templated classes, calls to the base class
  // methods must be qualified or use this->. Electing to do the former with the
  // following using declarations.
  using CounterValueOutputBase<T>::IsEnabled;
  using CounterValueOutputBase<T>::UpdateValue;
  using CounterValueOutputBase<T>::GetValue;

  // Constructor and destructor.
  SimpleCounter() : CounterValueOutputBase<T>() {}
  SimpleCounter(std::string name, const T &initial)
      : CounterValueOutputBase<T>(std::move(name), initial) {}
  explicit SimpleCounter(std::string name)
      : SimpleCounter(std::move(name), T()) {}
  SimpleCounter &operator=(const SimpleCounter &) = delete;
  ~SimpleCounter() override = default;

  // Implementing the methods from the CounterValueIncrementInterface<T>. Note
  // that the methods are declared final to enable de-virtualization
  // optimizations in the compiler.
  void Increment(const T &val) final {
    if (IsEnabled()) UpdateValue(GetValue() + val);
  }
  void Decrement(const T &val) final {
    if (IsEnabled()) UpdateValue(GetValue() - val);
  }
  void SetValue(const T &val) final {
    if (IsEnabled()) UpdateValue(val);
  }

  // From CounterValueOutputInterface<T>. This method is not declared final
  // to make it possible to customize formatting of the string in derived
  // classes.
  std::string ToString() const override { return absl::StrCat(GetValue()); }
};

// A complex counter that calls a function on its input value. If the
// function returns true, then the functions' computed output value is used to
// update the counter. The function can be any function object that can be cast
// to the ProcessingFunction type, including free functions, class methods,
// or call operators on class instances. This allows the function object to
// maintain state which enables more advanced computations, such as max/min
// etc. The fact that the counter is only updated when the function returns
// true allows for input samples to be filtered. This class has multiple
// inheritance from both the input interface and the output base class. The
// input interface is pure virtual, so there is no multiple implementation
// inheritance. There is also no possibility of a diamond pattern. The input
// interface inheritance is also necessary should instances of this class be
// used as a listener to another counter.
template <typename In, typename Out = In>
class FunctionCounter : public CounterValueOutputBase<Out>,
                        public CounterValueSetInterface<In> {
  // Static checks on the template argument type. The IsMemberOfVariant<T> check
  // is repeated to simplify error messages. If it is omitted and T is not in
  // the counter type, additional error messages may be generated for each of
  // the methods inherited from CounterBaseInterface and CounterValueOutputBase.
  static_assert(
      mpact::sim::generic::IsMemberOfVariant<CounterValue, Out>::value,
      "Template argument type Out is not in CounterValue variant.");

 public:
  using ProcessingFunction = std::function<bool(const In &, Out *)>;
  // Since this class derives from templated classes, calls to the base class
  // methods must be qualified or use this->. Electing to do the former with the
  // following using declarations.
  using CounterValueOutputBase<Out>::IsEnabled;
  using CounterValueOutputBase<Out>::UpdateValue;
  using CounterValueOutputBase<Out>::GetValue;

  // Constructors and destructor. The name is mandatory for the constructor. The
  // initial value is optional and defaults to the default constructed value.
  // The processing function may be given in the constructor or assigned later.
  // If not passed in to the constructor it defaults to a function that always
  // returns false and thus never updates the counter value.
  template <typename F>
  FunctionCounter(std::string name, const Out &initial, F processing_function)
      : CounterValueOutputBase<Out>(std::move(name), initial),
        processing_function_(
            std::move(ProcessingFunction(processing_function))) {}
  template <typename F>
  FunctionCounter(std::string name, F processing_function)
      : FunctionCounter(std::move(name), Out(),
                        std::move(processing_function)) {}
  FunctionCounter(std::string name, const Out &initial)
      : FunctionCounter(std::move(name), initial,
                        [](const In &, Out *) -> bool { return false; }) {}
  explicit FunctionCounter(std::string name)
      : FunctionCounter(std::move(name), Out()) {}
  FunctionCounter &operator=(const FunctionCounter &) = delete;
  ~FunctionCounter() override = default;

  // Set the value processing function.
  template <typename F>
  void SetFunction(F fcn) {
    processing_function_ = std::move(ProcessingFunction(fcn));
  }

  // The following method is defined final to enable devirtualization
  // optimization in the compiler.
  // Process the input value and update the counter if indicated.
  void SetValue(const In &in_value) final {
    if (IsEnabled()) {
      Out out_value;
      if (processing_function_(in_value, &out_value)) UpdateValue(out_value);
    }
  }

  // From CounterValueOutputBase<T>. This method is not declared final
  // to make it possible to customize formatting of the string in derived
  // classes.
  std::string ToString() const override { return absl::StrCat(GetValue()); }

 private:
  ProcessingFunction processing_function_;
};

// Definition of ExportValue methods, one for each type in the CounterValue
// variant.
// NOTE: add a specialization for every new type added to the variant.
template <>
inline void CounterValueOutputBase<uint64_t>::ExportValue(
    mpact::sim::proto::ComponentValueEntry *entry) const {
  entry->set_uint64_value(GetValue());
}
template <>
inline void CounterValueOutputBase<int64_t>::ExportValue(
    mpact::sim::proto::ComponentValueEntry *entry) const {
  entry->set_sint64_value(GetValue());
}
template <>
inline void CounterValueOutputBase<double>::ExportValue(
    mpact::sim::proto::ComponentValueEntry *entry) const {
  entry->set_double_value(GetValue());
}

}  // namespace generic
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_GENERIC_COUNTERS_H_
