// 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/component.h"

#include <cstdint>
#include <memory>

#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.h"
#include "mpact/sim/generic/config.h"
#include "mpact/sim/generic/counters.h"
#include "mpact/sim/proto/component_data.pb.h"
#include "src/google/protobuf/text_format.h"

namespace {

using ::mpact::sim::generic::Component;
using ::mpact::sim::generic::Config;
using ::mpact::sim::generic::SimpleCounter;
using ::mpact::sim::proto::ComponentData;

constexpr char kTopName[] = "top";
constexpr char kChildName[] = "child";
constexpr char kSecondChildName[] = "second_child";

constexpr char kInt64CounterName[] = "int64_counter";
constexpr int64_t kInt64CounterValue = -123;

constexpr char kUint64CounterName[] = "uint64_counter";
constexpr uint64_t kUint64CounterValue = 456;

constexpr char kInt64ConfigName[] = "int64_config";
constexpr int64_t kInt64ConfigValue = -456;
constexpr int64_t kInt64ConfigImportValue = -654;

constexpr char kUint64ConfigName[] = "uint64_config";
constexpr uint64_t kUint64ConfigValue = 123;
constexpr uint64_t kUint64ConfigImportValue = 321;

// Proto to import.
constexpr char kImportProto[] = R"pb(
  name: "top"
  configuration { name: "int64_config" sint64_value: -654 }
  statistics { name: "int64_counter" sint64_value: -321 }
  component_data {
    name: "child"
    configuration { name: "uint64_config" uint64_value: 321 }
    statistics { name: "uint64_counter" uint64_value: 654 }
  }
)pb";

// Test fixture. Allocates two components, two counters and two config items.
// The counters and config items are not added to the components in the fixture,
// but rather in each test as needed.
class ComponentTest : public testing::Test {
 protected:
  ComponentTest()
      : top_(kTopName),
        child_(kChildName, &top()),
        int64_counter_(kInt64CounterName, kInt64CounterValue),
        uint64_counter_(kUint64CounterName, kUint64CounterValue),
        int64_config_(kInt64ConfigName, kInt64ConfigValue),
        uint64_config_(kUint64ConfigName, kUint64ConfigValue) {}

  Component &top() { return top_; }
  Component &child() { return child_; }
  SimpleCounter<int64_t> &int64_counter() { return int64_counter_; }
  SimpleCounter<uint64_t> &uint64_counter() { return uint64_counter_; }
  Config<int64_t> &int64_config() { return int64_config_; }
  Config<uint64_t> &uint64_config() { return uint64_config_; }

 private:
  Component top_;
  Component child_;
  SimpleCounter<int64_t> int64_counter_;
  SimpleCounter<uint64_t> uint64_counter_;
  Config<int64_t> int64_config_;
  Config<uint64_t> uint64_config_;
};

// Verify that the basic constructor works.
TEST_F(ComponentTest, Basic) { EXPECT_EQ(top().component_name(), kTopName); }

// Verify that the constructor that added the child component works. Also
// add another child component outside that constructor.
TEST_F(ComponentTest, ChildComponent) {
  EXPECT_EQ(child().component_name(), kChildName);
  EXPECT_EQ(child().parent(), &top());
  EXPECT_EQ(top().GetChildComponent(kChildName), &child());
  Component second_child(kSecondChildName);
  EXPECT_TRUE(child().AddChildComponent(second_child).ok());
  EXPECT_EQ(second_child.parent(), &child());
  ASSERT_EQ(child().GetChildComponent(kSecondChildName), &second_child);
  EXPECT_EQ(
      top().GetChildComponent(kChildName)->GetChildComponent(kSecondChildName),
      &second_child);
}

// Add counter objects to the two components. Ensure that the counters are
// found in the expected component.
TEST_F(ComponentTest, ComponentsWithCounters) {
  auto *top_counter = &int64_counter();
  auto *child_counter = &uint64_counter();

  EXPECT_TRUE(top().AddCounter(top_counter).ok());
  EXPECT_TRUE(child().AddCounter(child_counter).ok());

  EXPECT_EQ(top().GetCounter(kInt64CounterName), top_counter);
  EXPECT_EQ(top().GetCounter(kUint64CounterName), nullptr);
  EXPECT_EQ(child().GetCounter(kInt64CounterName), nullptr);
  EXPECT_EQ(child().GetCounter(kUint64CounterName), child_counter);
}

// Add config objects to the two components. Ensure that the config objects
// are found in the expected component.
TEST_F(ComponentTest, ComponentsWithConfigs) {
  auto *top_config = &int64_config();
  auto *child_config = &uint64_config();

  EXPECT_TRUE(top().AddConfig(top_config).ok());
  EXPECT_TRUE(child().AddConfig(child_config).ok());

  EXPECT_EQ(top().GetConfig(kInt64ConfigName), top_config);
  EXPECT_EQ(top().GetConfig(kUint64ConfigName), nullptr);
  EXPECT_EQ(child().GetConfig(kInt64ConfigName), nullptr);
  EXPECT_EQ(child().GetConfig(kUint64ConfigName), child_config);
}

// Verify the import done callback propagates.
TEST_F(ComponentTest, ImportDoneCallback) {
  bool top_flag = false;
  bool child_flag = false;
  top().AddImportDoneCallback([&top_flag]() -> void { top_flag = true; });
  child().AddImportDoneCallback([&child_flag]() -> void { child_flag = true; });
  top().ImportDone();
  EXPECT_TRUE(top_flag);
  EXPECT_TRUE(child_flag);
}

// Add config entries and counters to the components with their default values,
// then export the components to a proto, and verify the proto against the
// expected value.
TEST_F(ComponentTest, ExportTest) {
  auto *top_config = &int64_config();
  auto *child_config = &uint64_config();
  EXPECT_TRUE(top().AddConfig(top_config).ok());
  EXPECT_TRUE(child().AddConfig(child_config).ok());

  auto *top_counter = &int64_counter();
  auto *child_counter = &uint64_counter();
  EXPECT_TRUE(top().AddCounter(top_counter).ok());
  EXPECT_TRUE(child().AddCounter(child_counter).ok());

  auto exported_proto = std::make_unique<ComponentData>();
  EXPECT_TRUE(top().Export(exported_proto.get()).ok());
}

// Import a proto into the components. Verify that the value of config entries
// are updated, but the counters are not.
TEST_F(ComponentTest, ImportTest) {
  auto *top_config = &int64_config();
  auto *child_config = &uint64_config();
  EXPECT_TRUE(top().AddConfig(top_config).ok());
  EXPECT_TRUE(child().AddConfig(child_config).ok());

  auto *top_counter = &int64_counter();
  auto *child_counter = &uint64_counter();
  EXPECT_TRUE(top().AddCounter(top_counter).ok());
  EXPECT_TRUE(child().AddCounter(child_counter).ok());

  ComponentData from_text;
  EXPECT_TRUE(
      google::protobuf::TextFormat::ParseFromString(kImportProto, &from_text));

  // Verify original values.
  EXPECT_EQ(top_config->GetValue(), kInt64ConfigValue);
  EXPECT_EQ(child_config->GetValue(), kUint64ConfigValue);
  EXPECT_EQ(top_counter->GetValue(), kInt64CounterValue);
  EXPECT_EQ(child_counter->GetValue(), kUint64CounterValue);

  // Perform the import.
  EXPECT_TRUE(top().Import(from_text).ok());

  // Verify that the config values are changed to those specified in the proto.
  EXPECT_EQ(top_config->GetValue(), kInt64ConfigImportValue);
  EXPECT_EQ(child_config->GetValue(), kUint64ConfigImportValue);
  // But the counter values shouldn't have changed on import.
  EXPECT_EQ(top_counter->GetValue(), kInt64CounterValue);
  EXPECT_EQ(child_counter->GetValue(), kUint64CounterValue);
}

}  // namespace
