#include "power.hpp"

#include <map>
#include <string>
#include <utility>
#include <vector>

#include <gtest/gtest.h>
#include "boost/beast/http/status.hpp"  // NOLINT
#include "dbus_utility.hpp"
#include "snapshot_fixture.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "test/g3/mock_managed_store_test.hpp"
#include "sdbusplus/message/native_types.hpp"

namespace redfish {
namespace {

using ::dbus::utility::MapperGetSubTreePathsResponse;
using ::dbus::utility::MapperGetSubTreeResponse;
using ::managedStore::KeyType;
using ::managedStore::ManagedType;

TEST_F(SnapshotFixture, ChassisPowerStateListTest) {
  const std::string chassisId = "platform1";
  const std::string powerStatePath =
      "/xyz/openbmc_project/inventory/system/powerstate/";
  const std::string powerStatePrefix = "PRSNT_";
  const int numberOfPowerStates = 100;

  std::vector<std::string> powerStates;
  std::map<std::string, std::string> expectedState;
  for (int i = 0; i < numberOfPowerStates; i++) {
    std::string powerStateName = powerStatePrefix + std::to_string(i);
    std::string path = powerStatePath + powerStateName;
    KeyType key(ManagedType::kManagedProperty,
                "xyz.openbmc_project.EntityManager",
                sdbusplus::message::object_path(path),
                "xyz.openbmc_project.Inventory.Item", "Present");
    bool present = (i % 2 == 0);
    ASSERT_TRUE(
        dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
            managedStore::GetManagedObjectStore())
            ->upsertMockObjectIntoManagedStore(
                key,
                managedStore::MockManagedStoreTest::CreateValueType(present))
            .ok());

    expectedState.emplace(powerStateName, present ? "Enabled" : "Absent");
    powerStates.push_back(path);
  }
  KeyType key(ManagedType::kManagedSubtreePaths,
              "/xyz/openbmc_project/inventory", 0,
              {"xyz.openbmc_project.Inventory.Item.PowerState"});

  ASSERT_TRUE(dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
                  managedStore::GetManagedObjectStore())
                  ->upsertMockObjectIntoManagedStore(
                      key, managedStore::MockManagedStoreTest::CreateValueType(
                               std::move(powerStates)))
                  .ok());

  KeyType subtree_key(ManagedType::kManagedSubtree, "/xyz/openbmc_project", 0,
                      {"xyz.openbmc_project.Control.PowerSupplyAttributes"});

  MapperGetSubTreeResponse subtree_response = {};

  ASSERT_TRUE(
      dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore())
          ->upsertMockObjectIntoManagedStore(
              subtree_key, managedStore::MockManagedStoreTest::CreateValueType(
                               std::move(subtree_response)))
          .ok());

  handleChassisPowerGet(app_, CreateRequest(), share_async_resp_, chassisId);

  RunIoUntilDone();

  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);

  nlohmann::json& jsonValue = share_async_resp_->res.jsonValue;

  EXPECT_TRUE(jsonValue.contains("Oem"));
  EXPECT_TRUE(jsonValue["Oem"].contains("Google"));
  EXPECT_EQ(jsonValue["Oem"]["Google"]["@odata.type"],
            "#GooglePower.v1_0_0.GooglePower");
  EXPECT_TRUE(jsonValue["Oem"]["Google"].contains("GooglePowerStates"));
  EXPECT_EQ(jsonValue["Oem"]["Google"]["GooglePowerStates"].size(),
            numberOfPowerStates);

  for (const nlohmann::json& powerState :
       jsonValue["Oem"]["Google"]["GooglePowerStates"]) {
    EXPECT_TRUE(powerState.contains("Id"));
    std::string stateId = powerState["Id"];
    EXPECT_EQ(powerState["@odata.id"], "/redfish/v1/Chassis/" + chassisId +
                                           "/Power/Oem/Google/PowerStates/" +
                                           stateId);
    EXPECT_EQ(powerState["@odata.type"], "#GooglePowerState.GooglePowerState");
    EXPECT_EQ(powerState["Name"], "Power");
    EXPECT_TRUE(expectedState.contains(stateId));
    EXPECT_TRUE(powerState.contains("Status"));
    EXPECT_TRUE(powerState["Status"].contains("State"));
    EXPECT_EQ(powerState["Status"]["State"], expectedState[stateId]);
    expectedState.erase(stateId);
  }

  EXPECT_EQ(expectedState.size(), 0);
}

}  // namespace
}  // namespace redfish
