#include "app.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "pcie.hpp"
#include "snapshot_fixture.hpp"
#include "test/g3/mock_managed_store_test.hpp"

#include <nlohmann/json.hpp>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace redfish
{
namespace
{

using ::dbus::utility::DbusVariantType;
using ::dbus::utility::DBusPropertiesMap;
using ::dbus::utility::MapperGetSubTreeResponse;
using ::dbus::utility::MapperGetSubTreePathsResponse;
using ::dbus::utility::MapperGetSubTreeResponse;
using ::managedStore::KeyType;
using ::managedStore::ManagedType::kManagedAssociatedSubtree;
using ::managedStore::ManagedType::kManagedSubtreePaths;
using ::managedStore::ManagedType::kManagedPropertyMap;
using ::managedStore::ValueType;

TEST_F(SnapshotFixture_Platform5_Config7, GetPCIeDeviceSuccess)
{
    handleSystemPCIeDeviceGet(app_, CreateRequest(), share_async_resp_, "system",
                           "chassis8_1_Link_0");

    RunIoUntilDone();

    LOG(INFO) << share_async_resp_->res.jsonValue.dump(2);

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/Systems/system/PCIeDevices/chassis8_1_Link_0");
    EXPECT_EQ(json["@odata.type"], "#PCIeDevice.v1_4_0.PCIeDevice");
    EXPECT_EQ(json["Id"], "chassis8_1_Link_0");
    EXPECT_EQ(json["Name"], "PCIe Device");
    EXPECT_EQ(json["Manufacturer"], "Manufacturer");
    EXPECT_EQ(json["DeviceType"], "SingleFunction");

    nlohmann::json& functions = json["PCIeFunctions"];
    EXPECT_EQ(functions["@odata.id"],
              "/redfish/v1/Systems/system/PCIeDevices/chassis8_1_Link_0/PCIeFunctions");

    nlohmann::json& interface = json["PCIeInterface"];
    EXPECT_EQ(interface.size(), 2);
    EXPECT_EQ(interface["PCIeType"], "Gen5");
    EXPECT_EQ(interface["LanesInUse"], 8);

    nlohmann::json& chassis = json["Links"]["Chassis"];
    EXPECT_EQ(chassis.size(), 1);
    EXPECT_EQ(chassis["@odata.id"], "/redfish/v1/Chassis/chassis8_1");

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

TEST_F(SnapshotFixture_Platform5_Config7, GetPCIeDeviceMissing)
{
    handleSystemPCIeDeviceGet(app_, CreateRequest(), share_async_resp_, "system",
                           "missing");

    RunIoUntilDone();

    LOG(INFO) << share_async_resp_->res.jsonValue.dump(2);

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

TEST_F(SnapshotFixture_Platform5_Config7, GetPCIeDeviceWrongSystem)
{
    handleSystemPCIeDeviceGet(app_, CreateRequest(), share_async_resp_, "asdf",
                           "chassis8_1_Link_0");

    RunIoUntilDone();

    LOG(INFO) << share_async_resp_->res.jsonValue.dump(2);

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

TEST_F(SnapshotFixture_Platform5_Config7, getPCIeFunctionCollectionAvailable)
{
    handleSystemPCIeFunctionCollectionGet(app_, CreateRequest(),share_async_resp_,
        "system", "chassis8_1_Link_0");
    RunIoUntilDone();

    LOG(INFO) << share_async_resp_->res.jsonValue.dump(2);
    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/Systems/system/PCIeDevices/chassis8_1_Link_0/PCIeFunctions");
    EXPECT_EQ(json["@odata.type"], "#PCIeFunctionCollection.PCIeFunctionCollection");
    EXPECT_EQ(json["Name"], "PCIe Function Collection");

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

TEST_F(SnapshotFixture_Platform5_Config7, getPCIeFunctionGet)
{
    KeyType key(
        kManagedPropertyMap,
        "xyz.openbmc_project.Hb16Manager",
        sdbusplus::message::object_path(
            "/xyz/openbmc_project/inventory/pcie/chassis8_1_Link_0"),
        "xyz.openbmc_project.Inventory.Item.PCIeDevice");
    ASSERT_TRUE(
        managedStore::GetManagedObjectStore()
            ->upsertMockObjectIntoManagedStore(
                key,
                managedStore::MockManagedStoreTest::CreateValueType(
                    DBusPropertiesMap({
                        std::make_pair("Function1DeviceId", DbusVariantType("OK"))
                    }))
            ).ok());

    handleSystemPCIeFunctionGet(app_, CreateRequest(),share_async_resp_,
        "system", "chassis8_1_Link_0", "1");
    RunIoUntilDone();

    LOG(INFO) <<  share_async_resp_->res.jsonValue.dump(2);
    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/Systems/system/PCIeDevices/chassis8_1_Link_0/PCIeFunctions/1");
    EXPECT_EQ(json["@odata.type"], "#PCIeFunction.v1_2_0.PCIeFunction");
    EXPECT_EQ(json["Name"], "PCIe Function");

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

MapperGetSubTreePathsResponse CreateMockSystemSubTree(){
    return MapperGetSubTreePathsResponse(
        {"/xyz/openbmc_project/inventory/system/board/platform5/system1",
        "/xyz/openbmc_project/inventory/system/board/platform5/system2"});
}

TEST_F(SnapshotFixture_Platform5_Config7, GetMultiHostsPCIeDeviceSuccess)
{
    std::string systemName = "system1";

    KeyType key1(
        kManagedSubtreePaths, "/", 0,
        {"xyz.openbmc_project.Inventory.Item.System"}
    );
    std::shared_ptr<ValueType> mockSystemSubTreeResponse =
        managedStore::MockManagedStoreTest::CreateValueType(CreateMockSystemSubTree());
    ASSERT_TRUE(managedStore::GetManagedObjectStore()
    ->upsertMockObjectIntoManagedStore(key1, mockSystemSubTreeResponse).ok());

    handlePCIeDeviceCollectionGet(app_, CreateRequest(), share_async_resp_, systemName);

    RunIoUntilDone();

    LOG(INFO) << share_async_resp_->res.jsonValue.dump(2);
    EXPECT_EQ(share_async_resp_->res.result(), boost::beast::http::status::ok);

    nlohmann::json& json = share_async_resp_->res.jsonValue;
    EXPECT_EQ(json["@odata.id"],
              "/redfish/v1/Systems/system1/PCIeDevices");
    EXPECT_EQ(json["@odata.type"], "#PCIeDeviceCollection.PCIeDeviceCollection");
    EXPECT_EQ(json["Name"], "PCIe Device Collection");
}

} // namespace
} // namespace redfish
