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

#include "NvidiaDriverInformation.hpp"

#include "Utils.hpp"

#include <MctpRequester.hpp>
#include <NvidiaGpuMctpVdm.hpp>
#include <OcpMctpVdm.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/message/native_types.hpp>

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

const std::string softwareInventoryPath = "/xyz/openbmc_project/software/";

NvidiaDriverInformation::NvidiaDriverInformation(
    std::shared_ptr<sdbusplus::asio::connection>& conn,
    mctp::MctpRequester& mctpRequester, const std::string& name,
    const uint8_t eid, sdbusplus::asio::object_server& objectServer,
    const sdbusplus::object_path& associationEndpoint,
    const std::optional<std::string>& manufacturer) :
    eid(eid), conn(conn), mctpRequester(mctpRequester)
{
    const int rc = gpu::encodeGetDriverInformationRequest(0, request);
    if (rc == 0)
    {
        requestEncoded = true;
    }
    else
    {
        lg2::error(
            "Failed to encode Driver Information request for eid {EID}, rc={RC}",
            "EID", eid, "RC", rc);
    }

    const std::string dbusPath = softwareInventoryPath + escapeName(name);

    versionInterface = objectServer.add_interface(
        dbusPath, "xyz.openbmc_project.Software.Version");

    versionInterface->register_property<std::string>("Version", "");

    versionInterface->register_property<std::string>(
        "Purpose", "xyz.openbmc_project.Software.Version.VersionPurpose.Other");

    if (!versionInterface->initialize())
    {
        lg2::error(
            "Error initializing Version interface for Driver Information, eid={EID}",
            "EID", eid);
    }

    std::vector<Association> associations;
    associations.emplace_back("running", "ran_on", associationEndpoint);

    associationInterface =
        objectServer.add_interface(dbusPath, association::interface);

    associationInterface->register_property("Associations", associations);

    if (!associationInterface->initialize())
    {
        lg2::error(
            "Error initializing Association interface for Driver Information, eid={EID}",
            "EID", eid);
    }

    if (manufacturer)
    {
        assetInterface = objectServer.add_interface(
            dbusPath, "xyz.openbmc_project.Inventory.Decorator.Asset");

        assetInterface->register_property("Manufacturer", *manufacturer);

        if (!assetInterface->initialize())
        {
            lg2::error(
                "Error initializing Asset interface for Driver Information, eid={EID}",
                "EID", eid);
        }
    }
}

void NvidiaDriverInformation::processResponse(const std::error_code& ec,
                                              std::span<const uint8_t> buffer)
{
    if (ec)
    {
        lg2::error(
            "Error updating Driver Information for eid {EID} : sending message over MCTP failed, rc={RC}",
            "EID", eid, "RC", ec.message());
        return;
    }

    ocp::accelerator_management::CompletionCode cc{};
    uint16_t reasonCode = 0;
    gpu::DriverState driverState{};
    std::string driverVersion;

    const int rc = gpu::decodeGetDriverInformationResponse(
        buffer, cc, reasonCode, driverState, driverVersion);

    if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
    {
        lg2::error(
            "Error updating Driver Information for eid {EID} : decode failed, rc={RC}, cc={CC}, reasonCode={REASON}",
            "EID", eid, "RC", rc, "CC", static_cast<uint8_t>(cc), "REASON",
            reasonCode);
        return;
    }

    versionInterface->set_property("Version", driverVersion);
}

void NvidiaDriverInformation::update()
{
    if (!requestEncoded)
    {
        return;
    }

    mctpRequester.sendRecvMsg(
        eid, request,
        [weak{weak_from_this()}](const std::error_code& ec,
                                 std::span<const uint8_t> buffer) {
            std::shared_ptr<NvidiaDriverInformation> self = weak.lock();
            if (!self)
            {
                lg2::error("invalid reference to NvidiaDriverInformation");
                return;
            }
            self->processResponse(ec, buffer);
        });
}
