// 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 use-case. 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_
