// 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_CONFIG_H_
#define MPACT_SIM_GENERIC_CONFIG_H_

#include <cstdint>
#include <functional>
#include <string>
#include <variant>
#include <vector>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/variant_helper.h"
#include "mpact/sim/proto/component_data.pb.h"

// This file defines a configuration type that is intended to be used in
// a simulator to access values that are specified at run time, such as the
// depth of a fifo, etc. The idea is that configuration entries are instantiated
// in software components, optionally with a default value. Prior to the start
// of the simulation, a master configuration utility (not part of this class),
// reads in configuration data for each software component, and sets the value
// for each configuration entry accordingly. The master configuration utility
// is intended read a proto as defined in
// //proto/component_data.proto. GCL (go/gcl)
// will be one method by which this proto can be generated.

namespace mpact {
namespace sim {
namespace generic {

struct PhysicalValue {
  double value;
  proto::SIPrefix si_prefix;
  proto::SIUnit si_unit;

  // Constructors.
  explicit PhysicalValue(double value)
      : PhysicalValue(value, proto::SIPrefix::PREFIX_NONE,
                      proto::SIUnit::UNIT_NONE) {}
  PhysicalValue(double value, proto::SIUnit unit)
      : PhysicalValue(value, proto::SIPrefix::PREFIX_NONE, unit) {}
  PhysicalValue(double value_, proto::SIPrefix prefix, proto::SIUnit unit)
      : value(value_), si_prefix(prefix), si_unit(unit) {}
};

// Variant value type of the config object. Only some types are supported.
// Additional types may be added in the future. If new types are added,
// the proto definition in component_data.proto will need to be updated
// accordingly, as well as adding additional specializations for the ExportValue
// and ImportValue methods at the bottom of this file.
using ConfigValue =
    std::variant<bool, int64_t, uint64_t, double, std::string, PhysicalValue>;

// This is the base class for a configuration entry. The value is type agnostic,
// as it uses the variant class. This class is primarily intended as a handle
// to access the configuration entry from a registry where configuration entries
// of different types may be stored.
class ConfigBase {
 public:
  explicit ConfigBase(absl::string_view name) : name_(name) {}
  ConfigBase() = delete;
  ConfigBase(const ConfigBase &) = delete;
  ConfigBase &operator=(const ConfigBase &) = delete;
  virtual ~ConfigBase() = default;

  // Return true if the config value has been set since construction.
  virtual bool HasConfigValue() const = 0;
  // Variant value accessors provide type agnostic access to config value.
  virtual ConfigValue GetConfigValue() const = 0;
  virtual absl::Status SetConfigValue(const ConfigValue &) = 0;
  // Exports the Config (name and value) to the proto message.
  virtual absl::Status Export(proto::ComponentValueEntry *entry) const = 0;
  virtual absl::Status Import(const proto::ComponentValueEntry *entry) = 0;

  const std::string &name() const { return name_; }

 private:
  std::string name_;
};

// The type specific class for the configuration entry. This class is templated
// on the type of the value. However, the template argument is restricted to
// those types that are in the ConfigValue variant. The static assert in the
// class enforces this and produces a reasonable error message in case an
// instantiation with a non supported type is attempted.
template <typename T>
class Config : public ConfigBase {
  static_assert(IsMemberOfVariant<ConfigValue, T>::value,
                "Template argument type is not in ConfigValue variant");

 public:
  using ValueWrittenCallback = std::function<void()>;

  Config() = delete;
  explicit Config(absl::string_view name) : ConfigBase(name) {}
  Config(absl::string_view name, T value) : ConfigBase(name), value_(value) {}
  ~Config() override = default;

  // Return true if the value has been updated since construction.
  bool HasConfigValue() const override { return has_value_; }
  // Get and Set the value of the configuration entry using the variant value.
  // The SetConfigValue method returns an error status if the member of the
  // variant in the config_value differs in type from that of the template
  // parameter.
  ConfigValue GetConfigValue() const override {
    return ConfigValue(GetValue());
  }
  absl::Status SetConfigValue(const ConfigValue &config_value) override {
    if (!std::holds_alternative<T>(config_value)) {
      return absl::InvalidArgumentError("Invalid type in ConfigValue argument");
    }
    SetValue(std::get<T>(config_value));
    has_value_ = true;
    return absl::OkStatus();
  }
  // Get and Set the value using the value type. These are passed/returned by
  // value. This is true even in the case where a std::string might be the value
  // type. This is a) not the expected common case, and b) accessing the values
  // of the configuration entries should not be on the critical path in any
  // simulator anyway.
  T GetValue() const { return value_; }
  void SetValue(T value) {
    has_value_ = true;
    value_ = value;
    for (auto const &callback : value_written_callback_vector_) {
      callback();
    }
  }
  // Add a callback on value written. Some configuration entries may be
  // modifiable during simulation, for example, an adjustable trade-off between
  // accuracy and speed, requiring a notification when the value changes. This
  // supports this usecase. Note, the callback is made whenever the value is
  // written to, not just if it changes.
  template <typename F>
  void AddValueWrittenCallback(F callback) {
    value_written_callback_vector_.push_back(ValueWrittenCallback(callback));
  }
  // Exports the configuration entry name and value to the proto message.
  absl::Status Export(proto::ComponentValueEntry *entry) const override {
    if (entry == nullptr) return absl::InvalidArgumentError("Entry is null");
    entry->set_name(name());
    ExportValue(entry);
    return absl::OkStatus();
  }
  // Imports the configuration entry value in the proto. Returns an error if the
  // name doesn't match or the entry is nullptr.
  absl::Status Import(const proto::ComponentValueEntry *entry) override {
    if (entry == nullptr) return absl::InvalidArgumentError("Entry is null");
    if (!entry->has_name() || (entry->name() != name()))
      return absl::InternalError(
          absl::StrCat("name mismatch: '", name(), "' != '",
                       (entry->has_name() ? entry->name() : ""), "'"));
    auto status = ImportValue(entry);
    if (!status.ok()) return status;
    return absl::OkStatus();
  }

 private:
  // Note, the following two methods are declared in this class, but defined
  // in specializations outside the class, as each specialization requires
  // writing to a different field in the proto message.
  // Exports the value to the proto message.
  void ExportValue(proto::ComponentValueEntry *entry) const;
  // Imports the value from the proto message.
  absl::Status ImportValue(const proto::ComponentValueEntry *entry);
  bool has_value_ = false;
  T value_;
  std::vector<ValueWrittenCallback> value_written_callback_vector_;
};

// The following specializations for the ExportValue and ImportValue methods are
// declared as inline to avoid a warning for potentially generating an ODR
// violation.
// ExportValue() specializations for the types in the ConfigValue variant.
// NOTE: add a specialization for every new type added to the variant.
template <>
inline void Config<bool>::ExportValue(proto::ComponentValueEntry *entry) const {
  entry->set_bool_value(GetValue());
}
template <>
inline void Config<int64_t>::ExportValue(
    proto::ComponentValueEntry *entry) const {
  entry->set_sint64_value(GetValue());
}
template <>
inline void Config<uint64_t>::ExportValue(
    proto::ComponentValueEntry *entry) const {
  entry->set_uint64_value(GetValue());
}
template <>
inline void Config<double>::ExportValue(
    proto::ComponentValueEntry *entry) const {
  entry->set_double_value(GetValue());
}
template <>
inline void Config<std::string>::ExportValue(
    proto::ComponentValueEntry *entry) const {
  entry->set_string_value(GetValue());
}
template <>
inline void Config<PhysicalValue>::ExportValue(
    proto::ComponentValueEntry *entry) const {
  auto *pvalue = entry->mutable_physical_value();
  const PhysicalValue &value = GetValue();
  pvalue->set_value(value.value);
  pvalue->set_si_prefix(value.si_prefix);
  pvalue->set_si_unit(value.si_unit);
}
// ImportValue() specializations for the types in the ConfigValue variant.
// NOTE: add a specialization for every new type added to the variant.
template <>
inline absl::Status Config<bool>::ImportValue(
    const proto::ComponentValueEntry *entry) {
  if (!entry->has_bool_value()) return absl::InternalError("No valid value");
  SetValue(entry->bool_value());
  return absl::OkStatus();
}
template <>
inline absl::Status Config<int64_t>::ImportValue(
    const proto::ComponentValueEntry *entry) {
  if (!entry->has_sint64_value()) return absl::InternalError("No valid value");
  SetValue(entry->sint64_value());
  return absl::OkStatus();
}
template <>
inline absl::Status Config<uint64_t>::ImportValue(
    const proto::ComponentValueEntry *entry) {
  if (!entry->has_uint64_value()) return absl::InternalError("No valid value");
  SetValue(entry->uint64_value());
  return absl::OkStatus();
}
template <>
inline absl::Status Config<double>::ImportValue(
    const proto::ComponentValueEntry *entry) {
  if (!entry->has_double_value()) return absl::InternalError("No valid value");
  SetValue(entry->double_value());
  return absl::OkStatus();
}
template <>
inline absl::Status Config<std::string>::ImportValue(
    const proto::ComponentValueEntry *entry) {
  if (!entry->has_string_value()) return absl::InternalError("No valid value");
  SetValue(entry->string_value());
  return absl::OkStatus();
}

template <>
inline absl::Status Config<PhysicalValue>::ImportValue(
    const proto::ComponentValueEntry *entry) {
  if (!entry->has_physical_value())
    return absl::InternalError("No valid value");
  SetValue(PhysicalValue(entry->physical_value().value(),
                         entry->physical_value().si_prefix(),
                         entry->physical_value().si_unit()));
  return absl::OkStatus();
}

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

#endif  // MPACT_SIM_GENERIC_CONFIG_H_
