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

#include "NvidiaGpuClockFrequencyMetric.hpp"

#include "NvidiaUtils.hpp"
#include "Utils.hpp"

#include <bits/basic_string.h>

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

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

using namespace std::literals;

static constexpr uint32_t mhzToHzFactor = 1'000'000;

NvidiaGpuClockFrequencyMetric::NvidiaGpuClockFrequencyMetric(
    mctp::MctpRequester& mctpRequester, const std::string& name, uint8_t eid,
    sdbusplus::asio::object_server& objectServer) :
    mctpRequester(mctpRequester), name(name), eid(eid),
    objectServer(objectServer)
{
    const int rc = gpu::encodeGetCurrentClockFrequencyRequest(
        0, gpu::ClockType::GRAPHICS_CLOCK, requestBuffer);
    if (rc == 0)
    {
        requestEncoded = true;
    }
    else
    {
        lg2::error(
            "Failed to encode clock frequency request for {NAME}: rc={RC}",
            "NAME", name, "RC", rc);
    }

    const sdbusplus::object_path inventoryPath = inventoryPrefix / this->name;
    const std::string metricDbusPath =
        metricPath + this->name + "/OperatingFrequency";

    metricInterface = objectServer.add_interface(
        metricDbusPath, "xyz.openbmc_project.Metric.Value");
    metricInterface->register_property(
        "Unit", "xyz.openbmc_project.Metric.Value.Unit.Frequency"s);
    metricInterface->register_property("Value", 0.0);
    if (!metricInterface->initialize())
    {
        lg2::error(
            "Error initializing Clock Frequency Metric interface for {NAME}, eid={EID}",
            "NAME", name, "EID", eid);
    }

    associationInterface =
        objectServer.add_interface(metricDbusPath, association::interface);
    std::vector<Association> associations;
    associations.emplace_back("measuring", "measured_by", inventoryPath);
    associationInterface->register_property("Associations", associations);
    if (!associationInterface->initialize())
    {
        lg2::error(
            "Error initializing Association interface for Clock Frequency Metric for {NAME}, eid={EID}",
            "NAME", name, "EID", eid);
    }
}

NvidiaGpuClockFrequencyMetric::~NvidiaGpuClockFrequencyMetric()
{
    objectServer.remove_interface(metricInterface);
    objectServer.remove_interface(associationInterface);
}

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

    mctpRequester.sendRecvMsg(
        eid, requestBuffer,
        [weak{weak_from_this()}](const std::error_code& ec,
                                 std::span<const uint8_t> buffer) {
            auto self = weak.lock();
            if (!self)
            {
                lg2::error("Invalid NvidiaGpuClockFrequencyMetric reference");
                return;
            }
            self->handleResponse(ec, buffer);
        });
}

void NvidiaGpuClockFrequencyMetric::handleResponse(
    const std::error_code& ec, std::span<const uint8_t> buffer)
{
    if (ec)
    {
        lg2::error(
            "Error reading clock frequency for {NAME}: MCTP failed, rc={RC}",
            "NAME", name, "RC", ec.message());
        return;
    }

    ocp::accelerator_management::CompletionCode cc{};
    uint16_t reasonCode = 0;
    uint32_t clockFrequencyMhz = 0;

    int rc = gpu::decodeGetCurrentClockFrequencyResponse(buffer, cc, reasonCode,
                                                         clockFrequencyMhz);

    if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
    {
        lg2::error(
            "Error decoding clock frequency for {NAME}: rc={RC}, cc={CC}, reasonCode={REASON}",
            "NAME", name, "RC", rc, "CC", static_cast<uint8_t>(cc), "REASON",
            reasonCode);
        return;
    }

    double freqHz = static_cast<double>(clockFrequencyMhz) * mhzToHzFactor;
    metricInterface->set_property("Value", freqHz);
}
