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

#include "NvidiaEthPort.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/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/message/native_types.hpp>

#include <array>
#include <cstdint>
#include <cstring>
#include <format>
#include <functional>
#include <memory>
#include <span>
#include <string>
#include <system_error>
#include <tuple>
#include <utility>
#include <vector>

using std::string;

using namespace std::literals;

static constexpr uint8_t permanentMacAddressTag = 2;

NvidiaEthPortMetrics::NvidiaEthPortMetrics(
    std::shared_ptr<sdbusplus::asio::connection>& conn,
    mctp::MctpRequester& mctpRequester, const std::string& name,
    const std::string& deviceName, const std::string& path, uint8_t eid,
    uint16_t portNumber, sdbusplus::asio::object_server& objectServer,
    const std::vector<std::pair<uint8_t, uint64_t>>& addresses) :
    eid(eid), portNumber(portNumber), path(path), conn(conn),
    mctpRequester(mctpRequester), objectServer(objectServer)
{
    const int rc = gpu::encodeGetEthernetPortTelemetryCountersRequest(
        0, portNumber, request);
    if (rc == 0)
    {
        requestEncoded = true;
    }
    else
    {
        lg2::error(
            "Failed to encode Ethernet Port Metrics request for EID={EID}, PortNumber={PN}, rc={RC}",
            "EID", eid, "PN", portNumber, "RC", rc);
    }

    const sdbusplus::object_path deviceDbusPath = inventoryPrefix / deviceName;

    const sdbusplus::object_path portDbusPath =
        inventoryPrefix / deviceName / name;

    const std::string metricsDbusPathPrefix =
        metricPath + std::format("port_{}_{}", deviceName, name);

    portInterface = objectServer.add_interface(
        portDbusPath, "xyz.openbmc_project.Inventory.Connector.Port");

    std::vector<Association> associations;
    associations.emplace_back("connected_to", "connecting", deviceDbusPath);

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

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

    portInterface->register_property(
        "PortProtocol",
        std::string("xyz.openbmc_project.Inventory.Connector.Port."
                    "PortProtocol.Ethernet"));

    for (const auto& [tag, value] : addresses)
    {
        if (tag != permanentMacAddressTag)
        {
            continue;
        }

        std::array<uint8_t, 6> mac{};
        std::memcpy(mac.data(), &value, sizeof(mac));
        const std::string macStr =
            std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", mac[0],
                        mac[1], mac[2], mac[3], mac[4], mac[5]);

        const sdbusplus::object_path ndfDbusPath =
            inventoryPrefix / deviceName / "NetworkDeviceFunctions" / name;

        networkDeviceFunctionInterface = objectServer.add_interface(
            ndfDbusPath, "xyz.openbmc_project.Inventory.Item.NetworkInterface");
        networkDeviceFunctionInterface->register_property("MACAddress", macStr);
        if (!networkDeviceFunctionInterface->initialize())
        {
            lg2::error(
                "Error initializing NetworkDeviceFunction interface, eid={EID}, portNumber={PN}",
                "EID", eid, "PN", portNumber);
        }

        std::vector<Association> ndfAssociations;
        ndfAssociations.emplace_back("exposed_by", "exposing", deviceDbusPath);
        ndfAssociations.emplace_back("assigned_to", "assigning", portDbusPath);
        networkDeviceFunctionAssociationInterface =
            objectServer.add_interface(ndfDbusPath, association::interface);
        networkDeviceFunctionAssociationInterface->register_property(
            "Associations", ndfAssociations);
        if (!networkDeviceFunctionAssociationInterface->initialize())
        {
            lg2::error(
                "Error initializing NetworkDeviceFunction Association interface, eid={EID}, portNumber={PN}",
                "EID", eid, "PN", portNumber);
        }
        break;
    }

    static constexpr auto telemetryMetrics =
        std::to_array<std::tuple<uint8_t, const char*, const std::string*>>({
            {0, "/nic/rx_bytes", &metricUnitBytes},
            {1, "/nic/tx_bytes", &metricUnitBytes},
            {2, "/nic/rx_unicast_frames", &metricUnitCount},
            {3, "/nic/rx_multicast_frames", &metricUnitCount},
            {4, "/nic/rx_broadcast_frames", &metricUnitCount},
            {5, "/nic/tx_unicast_frames", &metricUnitCount},
            {6, "/nic/tx_multicast_frames", &metricUnitCount},
            {7, "/nic/tx_broadcast_frames", &metricUnitCount},
            {8, "/nic/rx_fcs_errors", &metricUnitCount},
            {9, "/nic/rx_frame_alignment_errors", &metricUnitCount},
            {10, "/nic/rx_false_carrier_errors", &metricUnitCount},
            {11, "/nic/rx_undersize_frames", &metricUnitCount},
            {12, "/nic/rx_oversize_frames", &metricUnitCount},
            {13, "/nic/rx_pause_xon_frames", &metricUnitCount},
            {14, "/nic/rx_pause_xoff_frames", &metricUnitCount},
            {15, "/nic/tx_pause_xon_frames", &metricUnitCount},
            {16, "/nic/tx_pause_xoff_frames", &metricUnitCount},
            {17, "/nic/tx_single_collisions", &metricUnitCount},
            {18, "/nic/tx_multiple_collisions", &metricUnitCount},
            {19, "/nic/tx_late_collisions", &metricUnitCount},
            {20, "/nic/tx_excessive_collisions", &metricUnitCount},
        });

    for (const auto& [tag, metricName, unit] : telemetryMetrics)
    {
        metricValueInterface[tag] =
            objectServer.add_interface(metricsDbusPathPrefix + metricName,
                                       "xyz.openbmc_project.Metric.Value");

        metricValueInterface[tag]->register_property("Unit", *unit);
        metricValueInterface[tag]->register_property("Value", 0.0);

        std::vector<Association> associations;
        associations.emplace_back("measuring", "measured_by", portDbusPath);

        metricAssociationInterfaces[tag] = objectServer.add_interface(
            metricsDbusPathPrefix + metricName, association::interface);
        metricAssociationInterfaces[tag]->register_property("Associations",
                                                            associations);
        if (!metricValueInterface[tag]->initialize())
        {
            lg2::error(
                "Error initializing Ethernet Port Metric interface, eid={EID}, portNumber={PN}, metric={MN}",
                "EID", eid, "PN", portNumber, "MN", metricName);
        }

        if (!metricAssociationInterfaces[tag]->initialize())
        {
            lg2::error(
                "Error initializing Ethernet Port Metric Association interface, eid={EID}, portNumber={PN}, metric={MN}",
                "EID", eid, "PN", portNumber, "MN", metricName);
        }
    }

    if (!portInterface->initialize())
    {
        lg2::error(
            "Error initializing Ethernet Port interface, eid={EID}, portNumber={PN}",
            "EID", eid, "PN", portNumber);
    }

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

NvidiaEthPortMetrics::~NvidiaEthPortMetrics()
{
    objectServer.remove_interface(portInterface);
    objectServer.remove_interface(associationInterface);
    objectServer.remove_interface(networkDeviceFunctionInterface);
    objectServer.remove_interface(networkDeviceFunctionAssociationInterface);
    for (const auto& iface : metricValueInterface)
    {
        objectServer.remove_interface(iface);
    }
    for (const auto& iface : metricAssociationInterfaces)
    {
        objectServer.remove_interface(iface);
    }
}

void NvidiaEthPortMetrics::processResponse(
    const std::error_code& sendRecvMsgResult, std::span<const uint8_t> response)
{
    if (sendRecvMsgResult)
    {
        lg2::error(
            "Error updating Ethernet Port Metrics: sending message over MCTP failed, "
            "rc={RC}, EID={EID}, PortNumber={PN}",
            "RC", sendRecvMsgResult.message(), "EID", eid, "PN", portNumber);
        return;
    }

    ocp::accelerator_management::CompletionCode cc{};
    uint16_t reasonCode = 0;
    std::vector<std::pair<uint8_t, uint64_t>> telemetryValues;

    const int rc = gpu::decodeGetEthernetPortTelemetryCountersResponse(
        response, cc, reasonCode, telemetryValues);

    if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
    {
        lg2::error(
            "Error updating Ethernet Port Metrics: decode failed, "
            "rc={RC}, cc={CC}, reasonCode={RESC}, EID={EID}, PortNumber={PN}",
            "RC", rc, "CC", static_cast<uint8_t>(cc), "RESC", reasonCode, "EID",
            eid, "PN", portNumber);
        return;
    }

    for (const auto& [tag, value] : telemetryValues)
    {
        if (tag < maxTelemetryValues && metricValueInterface[tag])
        {
            metricValueInterface[tag]->set_property("Value",
                                                    static_cast<double>(value));
        }
    }
}

void NvidiaEthPortMetrics::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<NvidiaEthPortMetrics> self = weak.lock();
            if (!self)
            {
                lg2::error("Invalid reference to NvidiaEthPortMetrics");
                return;
            }
            self->processResponse(ec, buffer);
        });
}
