/*
 * SPDX-FileCopyrightText: Copyright OpenBMC Authors
 * SPDX-License-Identifier: Apache-2.0
 */

#include "MctpMockTestBase.hpp"
#include "MessagePackUnpackUtils.hpp"
#include "MockMctpRequester.hpp"
#include "NvidiaGpuMctpVdm.hpp"
#include "NvidiaPcieFunction.hpp"
#include "OcpMctpVdm.hpp"
#include "TestUtils.hpp"

#include <sdbusplus/exception.hpp>

#include <cstddef>
#include <cstdint>
#include <memory>
#include <span>
#include <string>
#include <system_error>
#include <vector>

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

namespace
{

const std::string functionIface =
    "xyz.openbmc_project.Inventory.Item.PCIeFunction";

// Build a SUCCESS QueryScalarGroupTelemetryV1 response on the PCIE_LINK
// message type with the supplied uint32_t telemetry values. test_utils has a
// V2 builder; the V1 command byte is needed for the GPU device path.
std::vector<uint8_t> buildPcieScalarTelemetryV1Response(
    const std::vector<uint32_t>& values)
{
    const size_t dataSize = values.size() * sizeof(uint32_t);
    std::vector<uint8_t> buf(
        ocp::accelerator_management::commonResponseSize + dataSize);
    PackBuffer pack(buf);
    ocp::accelerator_management::packHeader(
        pack, gpu::nvidiaPciVendorId,
        ocp::accelerator_management::MessageType::RESPONSE, 0,
        static_cast<uint8_t>(gpu::MessageType::PCIE_LINK));
    pack.pack(static_cast<uint8_t>(
        gpu::PcieLinkCommands::QueryScalarGroupTelemetryV1));
    pack.pack(static_cast<uint8_t>(
        ocp::accelerator_management::CompletionCode::SUCCESS));
    pack.pack(static_cast<uint16_t>(0)); // reserved
    pack.pack(static_cast<uint16_t>(dataSize));
    for (const uint32_t val : values)
    {
        pack.pack(val);
    }
    EXPECT_EQ(pack.getError(), 0);
    return buf;
}

class NvidiaPcieFunctionTest : public MctpMockTestBase
{
  protected:
    static std::shared_ptr<NvidiaPcieFunction> createFunction(
        const std::string& pcieDeviceName, gpu::DeviceIdentification deviceType,
        uint8_t functionNumber = 0, uint8_t eid = test_utils::defaultEid)
    {
        const std::string invPath =
            "/xyz/openbmc_project/inventory/" + pcieDeviceName;
        return std::make_shared<NvidiaPcieFunction>(
            bus(), requester(), pcieDeviceName, invPath, eid, functionNumber,
            objects(), deviceType);
    }

    static std::string functionPath(const std::string& pcieDeviceName,
                                    uint8_t functionNumber = 0)
    {
        return "/xyz/openbmc_project/inventory/" + pcieDeviceName +
               "/Function" + std::to_string(functionNumber);
    }
};

TEST_F(NvidiaPcieFunctionTest, ConstructorGpuDoesNotCrash)
{
    auto func = createFunction("pciefn_gpu_ctor",
                               gpu::DeviceIdentification::DEVICE_GPU);
    ASSERT_NE(func, nullptr);
}

TEST_F(NvidiaPcieFunctionTest, ConstructorPcieDoesNotCrash)
{
    auto func = createFunction("pciefn_pcie_ctor",
                               gpu::DeviceIdentification::DEVICE_PCIE);
    ASSERT_NE(func, nullptr);
}

TEST_F(NvidiaPcieFunctionTest, UpdatePcieSuccessSetsIds)
{
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce(mock_mctp::respondWith(
            {}, test_utils::buildPcieScalarTelemetryResponse(
                    {0x10DE, 0x2330, 0x10DE, 0x1234})));

    auto func =
        createFunction("pciefn_pcie", gpu::DeviceIdentification::DEVICE_PCIE);
    func->update();

    const std::string path = functionPath("pciefn_pcie");
    EXPECT_EQ(getProperty<uint16_t>(path, functionIface, "VendorId"), 0x10DE);
    EXPECT_EQ(getProperty<uint16_t>(path, functionIface, "DeviceId"), 0x2330);
    EXPECT_EQ(getProperty<uint16_t>(path, functionIface, "SubsystemVendorId"),
              0x10DE);
    EXPECT_EQ(getProperty<uint16_t>(path, functionIface, "SubsystemId"),
              0x1234);
}

TEST_F(NvidiaPcieFunctionTest, UpdateGpuSuccessSetsIds)
{
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce(
            mock_mctp::respondWith({}, buildPcieScalarTelemetryV1Response(
                                           {0x10DE, 0x2330, 0x10DE, 0x1234})));

    auto func =
        createFunction("pciefn_gpu", gpu::DeviceIdentification::DEVICE_GPU);
    func->update();

    const std::string path = functionPath("pciefn_gpu");
    EXPECT_EQ(getProperty<uint16_t>(path, functionIface, "VendorId"), 0x10DE);
    EXPECT_EQ(getProperty<uint16_t>(path, functionIface, "DeviceId"), 0x2330);
    EXPECT_EQ(getProperty<uint16_t>(path, functionIface, "SubsystemVendorId"),
              0x10DE);
    EXPECT_EQ(getProperty<uint16_t>(path, functionIface, "SubsystemId"),
              0x1234);
}

TEST_F(NvidiaPcieFunctionTest, UpdateInsufficientValuesNoSet)
{
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce(mock_mctp::respondWith(
            {}, test_utils::buildPcieScalarTelemetryResponse({1, 2, 3})));

    auto func =
        createFunction("pciefn_insuff", gpu::DeviceIdentification::DEVICE_PCIE);
    func->update();

    EXPECT_EQ(getProperty<uint16_t>(functionPath("pciefn_insuff"),
                                    functionIface, "VendorId"),
              0);
}

TEST_F(NvidiaPcieFunctionTest, UpdateTruncatesTo16Bits)
{
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce(mock_mctp::respondWith(
            {}, test_utils::buildPcieScalarTelemetryResponse(
                    {0x10001, 0x20002, 0x30003, 0x40004})));

    auto func =
        createFunction("pciefn_trunc", gpu::DeviceIdentification::DEVICE_PCIE);
    func->update();

    EXPECT_EQ(getProperty<uint16_t>(functionPath("pciefn_trunc"), functionIface,
                                    "VendorId"),
              1);
}

TEST_F(NvidiaPcieFunctionTest, UpdateGpuVerifiesRequestEncoding)
{
    // Copy the request bytes before completing the call: the reqMsg span is
    // a view into caller-owned memory, valid only during the call.
    std::vector<uint8_t> lastRequest;
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce([&](uint8_t /*eid*/, std::span<const uint8_t> reqMsg,
                      auto callback) {
            lastRequest.assign(reqMsg.begin(), reqMsg.end());
            callback(std::error_code{}, {});
        });

    auto func =
        createFunction("pciefn_gpu_enc", gpu::DeviceIdentification::DEVICE_GPU);
    func->update();

    ASSERT_FALSE(lastRequest.empty());

    UnpackBuffer unpack(lastRequest);
    ocp::accelerator_management::MessageType ocpMsgType{};
    uint8_t instanceId = 0;
    uint8_t msgType = 0;
    EXPECT_EQ(ocp::accelerator_management::unpackHeader(
                  unpack, gpu::nvidiaPciVendorId, ocpMsgType, instanceId,
                  msgType),
              0);
    EXPECT_EQ(msgType, static_cast<uint8_t>(gpu::MessageType::PCIE_LINK));

    uint8_t command = 0;
    unpack.unpack(command);
    EXPECT_EQ(command, static_cast<uint8_t>(
                           gpu::PcieLinkCommands::QueryScalarGroupTelemetryV1));
    EXPECT_EQ(unpack.getError(), 0);
}

TEST_F(NvidiaPcieFunctionTest, UpdatePcieVerifiesRequestEncoding)
{
    std::vector<uint8_t> lastRequest;
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce([&](uint8_t /*eid*/, std::span<const uint8_t> reqMsg,
                      auto callback) {
            lastRequest.assign(reqMsg.begin(), reqMsg.end());
            callback(std::error_code{}, {});
        });

    auto func = createFunction("pciefn_pcie_enc",
                               gpu::DeviceIdentification::DEVICE_PCIE);
    func->update();

    ASSERT_FALSE(lastRequest.empty());

    UnpackBuffer unpack(lastRequest);
    ocp::accelerator_management::MessageType ocpMsgType{};
    uint8_t instanceId = 0;
    uint8_t msgType = 0;
    EXPECT_EQ(ocp::accelerator_management::unpackHeader(
                  unpack, gpu::nvidiaPciVendorId, ocpMsgType, instanceId,
                  msgType),
              0);
    EXPECT_EQ(msgType, static_cast<uint8_t>(gpu::MessageType::PCIE_LINK));

    uint8_t command = 0;
    unpack.unpack(command);
    EXPECT_EQ(command, static_cast<uint8_t>(
                           gpu::PcieLinkCommands::QueryScalarGroupTelemetryV2));
    EXPECT_EQ(unpack.getError(), 0);
}

TEST_F(NvidiaPcieFunctionTest, UpdateRequestContainsCorrectEid)
{
    constexpr uint8_t testEid = 42;
    EXPECT_CALL(mctpMock, sendRecvMsg(testEid, testing::_, testing::_))
        .WillOnce(mock_mctp::respondWith({}, {}));

    auto func = createFunction(
        "pciefn_eid", gpu::DeviceIdentification::DEVICE_PCIE, 0, testEid);
    func->update();
}

TEST_F(NvidiaPcieFunctionTest, UpdateWrongCommandByteDecodeError)
{
    // Feed a V2 response to a GPU object (which decodes V1) → decode fails.
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce(mock_mctp::respondWith(
            {}, test_utils::buildPcieScalarTelemetryResponse(
                    {0x10DE, 0x2330, 0x10DE, 0x1234})));

    auto func = createFunction("pciefn_wrongcmd",
                               gpu::DeviceIdentification::DEVICE_GPU);
    func->update();

    EXPECT_EQ(getProperty<uint16_t>(functionPath("pciefn_wrongcmd"),
                                    functionIface, "VendorId"),
              0);
}

TEST_F(NvidiaPcieFunctionTest, UpdateMctpTransportErrorNoCrash)
{
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce(mock_mctp::respondWith(
            std::make_error_code(std::errc::timed_out), {}));

    auto func = createFunction("pciefn_mctp_err",
                               gpu::DeviceIdentification::DEVICE_PCIE);
    EXPECT_NO_THROW(func->update());
}

TEST_F(NvidiaPcieFunctionTest, UpdateEmptyBufferNoCrash)
{
    EXPECT_CALL(mctpMock, sendRecvMsg).WillOnce(mock_mctp::respondWith({}, {}));

    auto func =
        createFunction("pciefn_empty", gpu::DeviceIdentification::DEVICE_PCIE);
    EXPECT_NO_THROW(func->update());
}

TEST_F(NvidiaPcieFunctionTest, UpdateTinyBufferNoCrash)
{
    EXPECT_CALL(mctpMock, sendRecvMsg)
        .WillOnce(mock_mctp::respondWith({}, {0x00, 0x01}));

    auto func =
        createFunction("pciefn_tiny", gpu::DeviceIdentification::DEVICE_PCIE);
    EXPECT_NO_THROW(func->update());
}

// Destructor

TEST_F(NvidiaPcieFunctionTest, DestructorRemovesInterfaces)
{
    const std::string pcieDeviceName = "pcie_func_dtor";
    const std::string path = functionPath(pcieDeviceName);
    {
        const std::shared_ptr<NvidiaPcieFunction> function = createFunction(
            pcieDeviceName, gpu::DeviceIdentification::DEVICE_PCIE);
        ASSERT_NE(function, nullptr);
        EXPECT_NO_THROW(getProperty<uint16_t>(path, functionIface, "VendorId"));
    }
    drainPendingAsync();

    EXPECT_THROW(getProperty<uint16_t>(path, functionIface, "VendorId"),
                 sdbusplus::exception_t);
}

} // namespace
