#include "control.hpp"

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

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/functional/any_invocable.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "dbus_utility.hpp"
#include "test/redfish-core/lib/snapshot_fixture.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "test/g3/mock_managed_store.hpp"
#include "test/g3/mock_managed_store_test.hpp"
#include "sdbusplus/message/native_types.hpp"

namespace redfish {
namespace {

using ::dbus::utility::DbusVariantType;
using ::managedStore::KeyType;
using ::managedStore::ManagedType;
using ::managedStore::SimulateFailedAsyncPostDbusCallThreadSafeAction;
using ::managedStore::SimulateSuccessfulAsyncPostDbusCallThreadSafeAction;
using ::testing::_;
using ::testing::An;

constexpr absl::string_view kChassisId = "platform1";
constexpr absl::string_view kControlId = "PL1";
constexpr absl::string_view kControlId2 = "PL2";
constexpr absl::string_view kServiceName = "xyz.openbmc_project.ControlService";
constexpr absl::string_view kInterfaceName =
    "xyz.openbmc_project.Chassis.Control";

class ControlTest : public SnapshotFixture {
 protected:
  void TearDown() override {
    auto store = dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
        managedStore::GetManagedObjectStore());
    if (store != nullptr) {
      for (const auto& key : registered_keys_) {
        EXPECT_TRUE(store->evictMockObjectFromManagedStore(key).ok());
      }
    }
  }

  void UpsertMockObject(const KeyType& key,
                        const std::shared_ptr<managedStore::ValueType>& value) {
    auto store = dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
        managedStore::GetManagedObjectStore());
    ASSERT_NE(store, nullptr);
    ASSERT_TRUE(store->upsertMockObjectIntoManagedStore(key, value).ok());
    registered_keys_.push_back(key);
  }

  std::string GetControlPath(absl::string_view control_id) const {
    return absl::StrCat("/xyz/openbmc_project/control/", kChassisId, "/",
                        control_id);
  }

  void MockControlPaths(const std::vector<std::string>& control_ids) {
    std::vector<std::string> interfaces = {std::string(kInterfaceName)};
    KeyType key(ManagedType::kManagedSubtreePaths,
                absl::StrCat("/xyz/openbmc_project/control/", kChassisId), 0,
                interfaces);

    dbus::utility::MapperGetSubTreePathsResponse mockPaths;
    for (const auto& cid : control_ids) {
      mockPaths.push_back(GetControlPath(cid));
    }

    std::shared_ptr<managedStore::ValueType> value =
        managedStore::MockManagedStoreTest::CreateValueType(mockPaths);
    UpsertMockObject(key, value);
  }

  void MockMapperObject(absl::string_view control_id) {
    std::vector<std::string> interfaces = {std::string(kInterfaceName)};
    KeyType mapperKey(ManagedType::kManagedMapperObject,
                      GetControlPath(control_id), interfaces);

    dbus::utility::MapperGetObject mapperObject = {
        {std::string(kServiceName), {std::string(kInterfaceName)}}};
    std::shared_ptr<managedStore::ValueType> mapperValue =
        managedStore::MockManagedStoreTest::CreateValueType(mapperObject);
    UpsertMockObject(mapperKey, mapperValue);
  }

  void MockMapperObjectEmpty(absl::string_view control_id) {
    std::vector<std::string> interfaces = {std::string(kInterfaceName)};
    KeyType mapperKey(ManagedType::kManagedMapperObject,
                      GetControlPath(control_id), interfaces);

    dbus::utility::MapperGetObject mapperObject = {};
    std::shared_ptr<managedStore::ValueType> mapperValue =
        managedStore::MockManagedStoreTest::CreateValueType(mapperObject);
    UpsertMockObject(mapperKey, mapperValue);
  }

  void MockProperties(absl::string_view control_id,
                      const dbus::utility::DBusPropertiesMap& props) {
    KeyType propsKey(
        ManagedType::kManagedPropertyMap, kServiceName,
        sdbusplus::message::object_path(GetControlPath(control_id)),
        kInterfaceName);

    std::shared_ptr<managedStore::ValueType> propsValue =
        managedStore::MockManagedStoreTest::CreateValueType(props);
    UpsertMockObject(propsKey, propsValue);
  }

  void MockPropertiesError(absl::string_view control_id) {
    KeyType propsKey(
        ManagedType::kManagedPropertyMap, kServiceName,
        sdbusplus::message::object_path(GetControlPath(control_id)),
        kInterfaceName);

    dbus::utility::DBusPropertiesMap emptyProps = {};
    std::shared_ptr<managedStore::ValueType> propsErrorValue =
        managedStore::MockManagedStoreTest::CreateErrorValueType(
            emptyProps,
            boost::system::errc::make_error_code(
                boost::system::errc::io_error));
    UpsertMockObject(propsKey, propsErrorValue);
  }

  void MockMapperObjectError(absl::string_view control_id) {
    std::vector<std::string> interfaces = {std::string(kInterfaceName)};
    KeyType mapperKey(ManagedType::kManagedMapperObject,
                      GetControlPath(control_id), interfaces);

    dbus::utility::MapperGetObject emptyObject = {};
    std::shared_ptr<managedStore::ValueType> mapperErrorValue =
        managedStore::MockManagedStoreTest::CreateErrorValueType(
            emptyObject,
            boost::system::errc::make_error_code(
                boost::system::errc::io_error));
    UpsertMockObject(mapperKey, mapperErrorValue);
  }

  std::vector<KeyType> registered_keys_;
};

TEST_F(ControlTest, GetControlCollectionTestReturnsCorrectResponse) {
  MockControlPaths({std::string(kControlId), std::string(kControlId2)});

  getControlCollection(app_, CreateRequest(), share_async_resp_,
                       std::string(kChassisId));
  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"json(
  {
    "@odata.id": "/redfish/v1/Chassis/platform1/Controls",
    "@odata.type": "#ControlCollection.v1_0_0.ControlCollection",
    "Members": [
      {
        "@odata.id": "/redfish/v1/Chassis/platform1/Controls/PL1"
      },
      {
        "@odata.id": "/redfish/v1/Chassis/platform1/Controls/PL2"
      }
    ],
    "Members@odata.count": 2,
    "Name": "Control Collection"
  })json"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(ControlTest, GetControlConfigurationReturnsCorrectResponse) {
  MockMapperObject(kControlId);
  MockProperties(kControlId, {{"SetPoint", uint32_t{240}},
                              {"SetPointUnits", std::string("W")},
                              {"ControlType", std::string("Power")},
                              {"PhysicalContext", std::string("Processor")}});

  getControlConfiguration(app_, CreateRequest(), share_async_resp_,
                          std::string(kChassisId), std::string(kControlId));
  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"json(
  {
    "@odata.id": "/redfish/v1/Chassis/platform1/Controls/PL1",
    "@odata.type": "#Control.v1_5_1.Control",
    "ControlMode": "Manual",
    "ControlType": "Power",
    "Id": "PL1",
    "Name": "Chassis Control PL1",
    "PhysicalContext": "Processor",
    "SetPoint": 240,
    "SetPointUnits": "W"
  })json"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(ControlTest, GetControlConfigurationDisabledControl) {
  MockMapperObject(kControlId2);
  MockProperties(kControlId2, {{"SetPoint", uint32_t{0}},
                               {"SetPointUnits", std::string("W")}});

  getControlConfiguration(app_, CreateRequest(), share_async_resp_,
                          std::string(kChassisId), std::string(kControlId2));
  RunIoUntilDone();

  nlohmann::json& json = share_async_resp_->res.jsonValue;
  EXPECT_EQ(json, nlohmann::json::parse(R"json(
  {
    "@odata.id": "/redfish/v1/Chassis/platform1/Controls/PL2",
    "@odata.type": "#Control.v1_5_1.Control",
    "ControlMode": "Disabled",
    "Id": "PL2",
    "Name": "Chassis Control PL2"
  })json"));
  EXPECT_FALSE(json.contains("SetPointUnits"));
  EXPECT_FALSE(json.contains("SetPoint"));
  EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);
}

TEST_F(ControlTest, GetControlConfigurationNotFound) {
  MockMapperObjectEmpty(kControlId);

  getControlConfiguration(app_, CreateRequest(), share_async_resp_,
                          std::string(kChassisId), std::string(kControlId));
  RunIoUntilDone();

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

TEST_F(ControlTest, GetControlConfigurationDBusError) {
  MockMapperObject(kControlId);
  MockPropertiesError(kControlId);

  getControlConfiguration(app_, CreateRequest(), share_async_resp_,
                          std::string(kChassisId), std::string(kControlId));
  RunIoUntilDone();

  // Verify that internalError was invoked and returned 500
  EXPECT_EQ(share_async_resp_->res.result(),
            boost::beast::http::status::internal_server_error);
}



TEST_F(ControlTest, PatchControlConfigurationSuccess) {
  MockMapperObject(kControlId);
  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
          std::string(kServiceName), GetControlPath(kControlId),
          "org.freedesktop.DBus.Properties", "Set", std::string(kInterfaceName),
          "SetPoint", DbusVariantType(uint32_t{250})))
      .Times(1)
      .WillOnce(SimulateSuccessfulAsyncPostDbusCallThreadSafeAction::
                    SimulateSuccessfulAsyncPostDbusCall());

  patchControlConfiguration(app_, CreateRequest(R"({"SetPoint": 250})"),
                            share_async_resp_, std::string(kChassisId),
                            std::string(kControlId));
  RunIoUntilDone();

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

TEST_F(ControlTest, PatchControlConfigurationSetPropertyError) {
  MockMapperObject(kControlId);
  EXPECT_CALL(
      *dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
          managedStore::GetManagedObjectStore()),
      PostDbusCallToIoContextThreadSafe(
          _, An<absl::AnyInvocable<void(const boost::system::error_code&)>&&>(),
          std::string(kServiceName), GetControlPath(kControlId),
          "org.freedesktop.DBus.Properties", "Set", std::string(kInterfaceName),
          "SetPoint", DbusVariantType(uint32_t{250})))
      .Times(1)
      .WillOnce(SimulateFailedAsyncPostDbusCallThreadSafeAction::
                    SimulateFailedAsyncPostDbusCall());

  patchControlConfiguration(app_, CreateRequest(R"({"SetPoint": 250})"),
                            share_async_resp_, std::string(kChassisId),
                            std::string(kControlId));
  RunIoUntilDone();

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

TEST_F(ControlTest, PatchControlConfigurationMissingSetPoint) {
  patchControlConfiguration(app_, CreateRequest(R"({})"),
                            share_async_resp_, std::string(kChassisId),
                            std::string(kControlId));
  RunIoUntilDone();

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

TEST_F(ControlTest, PatchControlConfigurationNullSetPoint) {
  patchControlConfiguration(app_, CreateRequest(R"({"SetPoint": null})"),
                            share_async_resp_, std::string(kChassisId),
                            std::string(kControlId));
  RunIoUntilDone();

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

TEST_F(ControlTest, PatchControlConfigurationUnknownProperty) {
  patchControlConfiguration(app_, CreateRequest(R"({"OtherProperty": 250})"),
                            share_async_resp_, std::string(kChassisId),
                            std::string(kControlId));
  RunIoUntilDone();

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

TEST_F(ControlTest, PatchControlConfigurationInvalidSetPoint) {
  patchControlConfiguration(
      app_, CreateRequest(R"({"SetPoint": "invalid_string"})"),
      share_async_resp_, std::string(kChassisId), std::string(kControlId));
  RunIoUntilDone();

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

TEST_F(ControlTest, PatchControlConfigurationNotFound) {
  MockMapperObjectEmpty(kControlId);

  patchControlConfiguration(app_, CreateRequest(R"({"SetPoint": 250})"),
                            share_async_resp_, std::string(kChassisId),
                            std::string(kControlId));
  RunIoUntilDone();

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

TEST_F(ControlTest, PatchControlConfigurationDBusMapperError) {
  MockMapperObjectError(kControlId);

  patchControlConfiguration(app_, CreateRequest(R"({"SetPoint": 250})"),
                            share_async_resp_, std::string(kChassisId),
                            std::string(kControlId));
  RunIoUntilDone();

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

}  // namespace
}  // namespace redfish
