// 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.

#include "mpact/sim/generic/config.h"

#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "absl/container/btree_map.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.h"
#include "mpact/sim/proto/component_data.pb.h"
#include "src/google/protobuf/text_format.h"
#include "src/google/protobuf/util/message_differencer.h"

namespace {

using ::mpact::sim::generic::Config;
using ::mpact::sim::generic::ConfigBase;
using ::mpact::sim::generic::ConfigValue;
using ::mpact::sim::proto::ComponentData;
using ::mpact::sim::proto::ComponentValueEntry;

constexpr char kBoolConfigName[] = "BoolConfigName";
constexpr char kInt64ConfigName[] = "Int64ConfigName";
constexpr char kUint64ConfigName[] = "Uint64ConfigName";
constexpr char kDoubleConfigName[] = "DoubleConfigName";
constexpr char kStringConfigName[] = "StringConfigName";
constexpr char kProtoValue[] = R"pb(
  configuration { name: "BoolConfigName" bool_value: true }
  configuration { name: "Int64ConfigName" sint64_value: -123 }
  configuration { name: "Uint64ConfigName" uint64_value: 123 }
  configuration { name: "DoubleConfigName" double_value: 0.25 }
  configuration { name: "StringConfigName" string_value: "string value" }
)pb";
constexpr char kProtoNoName[] = R"pb(
  configuration { sint64_value: -123 }
  configuration { uint64_value: 123 }
  configuration { double_value: 0.25 }
  configuration { string_value: "string value" }
  configuration { bool_value: true }
)pb";
constexpr char kProtoWrongName[] = R"pb(
  configuration { name: "ConfigNameWrong" }
)pb";
constexpr char kProtoWrongValues[] = R"pb(
  configuration { name: "BoolConfigName" sint64_value: -123 }
  configuration { name: "Int64ConfigName" uint64_value: 123 }
  configuration { name: "Uint64ConfigName" double_value: 0.25 }
  configuration { name: "DoubleConfigName" string_value: "string value" }
  configuration { name: "StringConfigName" bool_value: true }
)pb";
constexpr bool kBoolValue = true;
constexpr int64_t kInt64Value = -123;
constexpr uint64_t kUint64Value = 123;
constexpr double kDoubleValue = 0.25;
constexpr char kStringValue[] = "string value";

// Simple test of construction and name property.
TEST(ConfigTest, BaseConstruction) {
  Config<bool> bool_config(kBoolConfigName);
  EXPECT_EQ(bool_config.name(), kBoolConfigName);
  Config<int64_t> int64_config(kInt64ConfigName);
  EXPECT_EQ(int64_config.name(), kInt64ConfigName);
  Config<uint64_t> uint64_config(kUint64ConfigName);
  EXPECT_EQ(uint64_config.name(), kUint64ConfigName);
  Config<double> double_config(kDoubleConfigName);
  EXPECT_EQ(double_config.name(), kDoubleConfigName);
  Config<std::string> string_config(kStringConfigName);
  EXPECT_EQ(string_config.name(), kStringConfigName);
}

// Testing that the value can be set and retrieved using the variant type.
TEST(ConfigTest, ConfigValue) {
  ConfigValue input_value;
  ConfigValue output_value;

  Config<bool> bool_config(kBoolConfigName);
  input_value = ConfigValue(kBoolValue);
  EXPECT_TRUE(bool_config.SetConfigValue(input_value).ok());
  output_value = bool_config.GetConfigValue();
  EXPECT_EQ(std::get<bool>(output_value), kBoolValue);

  Config<int64_t> int64_config(kInt64ConfigName);
  input_value = ConfigValue(kInt64Value);
  EXPECT_TRUE(int64_config.SetConfigValue(input_value).ok());
  output_value = int64_config.GetConfigValue();
  EXPECT_EQ(std::get<int64_t>(output_value), kInt64Value);

  Config<uint64_t> uint64_config(kUint64ConfigName);
  input_value = ConfigValue(kUint64Value);
  EXPECT_TRUE(uint64_config.SetConfigValue(input_value).ok());
  output_value = uint64_config.GetConfigValue();
  EXPECT_EQ(std::get<uint64_t>(output_value), kUint64Value);

  Config<double> double_config(kDoubleConfigName);
  input_value = ConfigValue(kDoubleValue);
  EXPECT_TRUE(double_config.SetConfigValue(input_value).ok());
  output_value = double_config.GetConfigValue();
  EXPECT_EQ(std::get<double>(output_value), kDoubleValue);

  Config<std::string> string_config(kStringConfigName);
  input_value = ConfigValue(std::string(kStringValue));
  EXPECT_TRUE(string_config.SetConfigValue(input_value).ok());
  output_value = string_config.GetConfigValue();
  EXPECT_EQ(std::get<std::string>(output_value), kStringValue);
}

// Testing that error is returned if a ConfigValue with the wrong type
// in the variant is passed int.
TEST(ConfigTest, WrongConfigValueType) {
  ConfigValue input_value;
  Config<bool> bool_config(kBoolConfigName);
  input_value = ConfigValue(kInt64Value);
  EXPECT_TRUE(absl::IsInvalidArgument(bool_config.SetConfigValue(input_value)));
}

// Testing that the initial values can be retrieved correctly.
TEST(ConfigTest, InitialValue) {
  Config<bool> bool_config(kBoolConfigName, kBoolValue);
  EXPECT_EQ(bool_config.GetValue(), kBoolValue);

  Config<int64_t> int64_config(kInt64ConfigName, kInt64Value);
  EXPECT_EQ(int64_config.GetValue(), kInt64Value);

  Config<uint64_t> uint64_config(kUint64ConfigName, kUint64Value);
  EXPECT_EQ(uint64_config.GetValue(), kUint64Value);

  Config<double> double_config(kDoubleConfigName, kDoubleValue);
  EXPECT_EQ(double_config.GetValue(), kDoubleValue);

  Config<std::string> string_config(kStringConfigName,
                                    std::string(kStringValue));
  EXPECT_EQ(string_config.GetValue(), kStringValue);
}

// Testing that the value can be set and retrieved using the typed call.
TEST(ConfigTest, TypedValue) {
  Config<bool> bool_config(kBoolConfigName);
  bool_config.SetValue(kBoolValue);
  EXPECT_EQ(bool_config.GetValue(), kBoolValue);

  Config<int64_t> int64_config(kInt64ConfigName);
  int64_config.SetValue(kInt64Value);
  EXPECT_EQ(int64_config.GetValue(), kInt64Value);

  Config<uint64_t> uint64_config(kUint64ConfigName);
  uint64_config.SetValue(kUint64Value);
  EXPECT_EQ(uint64_config.GetValue(), kUint64Value);

  Config<double> double_config(kDoubleConfigName);
  double_config.SetValue(kDoubleValue);
  EXPECT_EQ(double_config.GetValue(), kDoubleValue);

  Config<std::string> string_config(kStringConfigName);
  string_config.SetValue(std::string(kStringValue));
  EXPECT_EQ(string_config.GetValue(), kStringValue);
}

// Tests that the config entries correctly exports to a proto.
TEST(ConfigTest, ProtoExport) {
  Config<bool> bool_config(kBoolConfigName, kBoolValue);
  Config<int64_t> int64_config(kInt64ConfigName, kInt64Value);
  Config<uint64_t> uint64_config(kUint64ConfigName, kUint64Value);
  Config<double> double_config(kDoubleConfigName, kDoubleValue);
  Config<std::string> string_config(kStringConfigName,
                                    std::string(kStringValue));

  // Add config entries to vector of ConfigBase. Part of the motivation here
  // is that this is an intended use case for reading out the configuration
  // and exporting it to a proto. Saving the configuration after a simulation
  // is useful in post analysis to be able to tie together the configuration
  // information and the collected statistics.
  std::vector<ConfigBase *> config_vector;
  config_vector.push_back(&bool_config);
  config_vector.push_back(&int64_config);
  config_vector.push_back(&uint64_config);
  config_vector.push_back(&double_config);
  config_vector.push_back(&string_config);

  auto exported_proto = std::make_unique<ComponentData>();
  ComponentValueEntry *entry;
  for (auto const &config : config_vector) {
    entry = exported_proto->add_configuration();
    EXPECT_TRUE(config->Export(entry).ok());
  }

  // Ensure that the proto is parsed correctly.
  ComponentData fromText;
  EXPECT_TRUE(
      google::protobuf::TextFormat::ParseFromString(kProtoValue, &fromText));
  // The proto parsed from the string should be equal to that exported from
  // the configuration entries.
  EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(
      fromText, *exported_proto));
}

// Tests that the config entries correctly import values from a proto.
TEST(ConfigTest, ProtoImport) {
  Config<bool> bool_config(kBoolConfigName);
  Config<int64_t> int64_config(kInt64ConfigName);
  Config<uint64_t> uint64_config(kUint64ConfigName);
  Config<double> double_config(kDoubleConfigName);
  Config<std::string> string_config(kStringConfigName);

  // Add the configuration entries to a map from name to ConfigBase. This is to
  // mimic a use case where a proto is read in for a software component and the
  // values are imported into its configuration entries (stored in a registry).
  absl::btree_map<std::string, ConfigBase *> config_map;
  config_map.insert(std::make_pair(bool_config.name(), &bool_config));
  config_map.insert(std::make_pair(int64_config.name(), &int64_config));
  config_map.insert(std::make_pair(uint64_config.name(), &uint64_config));
  config_map.insert(std::make_pair(double_config.name(), &double_config));
  config_map.insert(std::make_pair(string_config.name(), &string_config));

  ComponentData fromText;
  // Parse the proto from text description.
  EXPECT_TRUE(
      google::protobuf::TextFormat::ParseFromString(kProtoValue, &fromText));
  // For each configuration entry, look up a config entry with a matching name
  // and import the proto value to the config.
  for (int index = 0; index < fromText.configuration_size(); index++) {
    const ComponentValueEntry &entry = fromText.configuration(index);
    if (entry.has_name() && config_map.contains(entry.name())) {
      ConfigBase *config = config_map.at(entry.name());
      EXPECT_TRUE(config->Import(&entry).ok());
    }
  }

  // Verify that the values are those specified in the proto.
  EXPECT_EQ(bool_config.GetValue(), kBoolValue);
  EXPECT_EQ(int64_config.GetValue(), kInt64Value);
  EXPECT_EQ(uint64_config.GetValue(), kUint64Value);
  EXPECT_EQ(double_config.GetValue(), kDoubleValue);
  EXPECT_EQ(string_config.GetValue(), kStringValue);
}

// Negative proto import test - nullptr entry.
TEST(ConfigTest, ImportFailNullProto) {
  Config<bool> bool_config(kBoolConfigName);
  Config<int64_t> int64_config(kInt64ConfigName);
  Config<uint64_t> uint64_config(kUint64ConfigName);
  Config<double> double_config(kDoubleConfigName);
  Config<std::string> string_config(kStringConfigName);

  std::vector<ConfigBase *> config_vector;
  config_vector.push_back(&bool_config);
  config_vector.push_back(&int64_config);
  config_vector.push_back(&uint64_config);
  config_vector.push_back(&double_config);
  config_vector.push_back(&string_config);

  // Expect each import to fail with invalid argument.
  for (auto *config : config_vector) {
    EXPECT_TRUE(absl::IsInvalidArgument(config->Import(nullptr)));
  }
}

// Negative proto import test - no name in configuration value.
TEST(ConfigTest, ImportFailNoNameInProto) {
  Config<bool> bool_config(kBoolConfigName);
  Config<int64_t> int64_config(kInt64ConfigName);
  Config<uint64_t> uint64_config(kUint64ConfigName);
  Config<double> double_config(kDoubleConfigName);
  Config<std::string> string_config(kStringConfigName);

  std::vector<ConfigBase *> config_vector;
  config_vector.push_back(&bool_config);
  config_vector.push_back(&int64_config);
  config_vector.push_back(&uint64_config);
  config_vector.push_back(&double_config);
  config_vector.push_back(&string_config);

  ComponentData fromText;
  // Parse the proto from text description.
  EXPECT_TRUE(
      google::protobuf::TextFormat::ParseFromString(kProtoNoName, &fromText));
  // Expect each import to fail with internal error.
  const ComponentValueEntry &entry = fromText.configuration(0);
  for (int index = 0; index < fromText.configuration_size(); index++) {
    EXPECT_TRUE(absl::IsInternal(config_vector[index]->Import(&entry)));
  }
}

// Negative proto import test - wrong names in configuration value.
TEST(ConfigTest, ImportFailWrongNameInProto) {
  Config<bool> bool_config(kBoolConfigName);
  Config<int64_t> int64_config(kInt64ConfigName);
  Config<uint64_t> uint64_config(kUint64ConfigName);
  Config<double> double_config(kDoubleConfigName);
  Config<std::string> string_config(kStringConfigName);

  std::vector<ConfigBase *> config_vector;
  config_vector.push_back(&bool_config);
  config_vector.push_back(&int64_config);
  config_vector.push_back(&uint64_config);
  config_vector.push_back(&double_config);
  config_vector.push_back(&string_config);

  ComponentData fromText;
  // Parse the proto from text description.
  EXPECT_TRUE(google::protobuf::TextFormat::ParseFromString(kProtoWrongName,
                                                            &fromText));
  // Expect each import to fail with internal error, as the proto message
  // passed in has a name that doesn't match the configuration entry.
  for (int index = 0; index < fromText.configuration_size(); index++) {
    const ComponentValueEntry &entry = fromText.configuration(index);
    EXPECT_TRUE(absl::IsInternal(config_vector[index]->Import(&entry)));
  }
}

// Negative proto import test - wrong value fields in the proto.
TEST(ConfigTest, ImportFailWrongValue) {
  Config<bool> bool_config(kBoolConfigName);
  Config<int64_t> int64_config(kInt64ConfigName);
  Config<uint64_t> uint64_config(kUint64ConfigName);
  Config<double> double_config(kDoubleConfigName);
  Config<std::string> string_config(kStringConfigName);

  // Add the configuration entries to a map from name to ConfigBase. This is to
  // mimic a use case where a proto is read in for a software component and the
  // values are imported into its configuration entries (stored in a registry).
  absl::btree_map<std::string, ConfigBase *> config_map;
  config_map.insert(std::make_pair(bool_config.name(), &bool_config));
  config_map.insert(std::make_pair(int64_config.name(), &int64_config));
  config_map.insert(std::make_pair(uint64_config.name(), &uint64_config));
  config_map.insert(std::make_pair(double_config.name(), &double_config));
  config_map.insert(std::make_pair(string_config.name(), &string_config));

  ComponentData fromText;
  // Parse the proto from text description.
  EXPECT_TRUE(google::protobuf::TextFormat::ParseFromString(kProtoWrongValues,
                                                            &fromText));
  // For each configuration entry, look up a config entry with a matching name
  // and import the proto value to the config. Because the value fields are
  // mismatches to the type of the config entry they should all fail with
  // internal errors.
  for (int index = 0; index < fromText.configuration_size(); index++) {
    const ComponentValueEntry &entry = fromText.configuration(index);
    if (entry.has_name() && config_map.contains(entry.name())) {
      ConfigBase *config = config_map.at(entry.name());
      EXPECT_TRUE(absl::IsInternal(config->Import(&entry)));
    }
  }
}

// Tests that the value written callback is made when the config entry is
// written to.
TEST(ConfigTest, Callback) {
  Config<bool> bool_config(kBoolConfigName);
  bool it_worked = false;
  bool_config.AddValueWrittenCallback(
      [&it_worked]() -> void { it_worked = true; });
  EXPECT_FALSE(it_worked);
  bool_config.SetValue(true);
  EXPECT_TRUE(it_worked);
}

}  // namespace
