/* Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
#include "l_mctp_infos.h"

namespace sml {

void l_mctp_infos::register_to(lua_State *L, luawrap::stack_table &t)
{
    luawrap::restore_stack_top _s(L);

    auto cls = luawrap::lua_class<l_mctp_infos>(L);
    cls.set("set_bmc_mctp_info", c_func_wrap(L, l_mctp_infos::set_bmc_mctp_info));
    cls.set("get_bmc_mctp_info", c_func_wrap(L, l_mctp_infos::get_bmc_mctp_info));
    cls.set("add_mctp_info", c_func_wrap(L, l_mctp_infos::add_mctp_info));
    cls.set("del_mctp_info", c_func_wrap(L, l_mctp_infos::del_mctp_info));
    cls.set("clean_mctp_info", c_func_wrap(L, l_mctp_infos::clean_mctp_info));
    cls.set("get_mctp_info", c_func_wrap(L, l_mctp_infos::get_mctp_info));

    t.set("mctp_infos", cls);
}

void l_mctp_infos::set_bmc_mctp_info(uint8_t bmc_eid, uint16_t bmc_phy_addr)
{
    std::lock_guard<std::mutex> guard(s_params.mutex);
    s_params.bmc_eid      = bmc_eid;
    s_params.bmc_phy_addr = bmc_phy_addr;
}

std::tuple<uint8_t, uint16_t> l_mctp_infos::get_bmc_mctp_info()
{
    std::lock_guard<std::mutex> guard(s_params.mutex);
    return {s_params.bmc_eid, s_params.bmc_phy_addr};
}

void l_mctp_infos::add_mctp_info(uint8_t controller_index, uint8_t eid, uint16_t phy_addr, uint16_t vendor_id)
{
    std::lock_guard<std::mutex> guard(s_params.mutex);
    s_params.mctp_infos.emplace(controller_index, mctp_info{eid, phy_addr, vendor_id});
}

void l_mctp_infos::del_mctp_info(uint8_t controller_index)
{
    std::lock_guard<std::mutex> guard(s_params.mutex);

    auto it = s_params.mctp_infos.find(controller_index);
    if (it != s_params.mctp_infos.end()) {
        s_params.mctp_infos.erase(it);
    }
}

void l_mctp_infos::clean_mctp_info()
{
    std::lock_guard<std::mutex> guard(s_params.mutex);
    s_params.mctp_infos.clear();
}

std::optional<std::tuple<uint16_t, uint16_t>> l_mctp_infos::get_mctp_info(uint8_t controller_index)
{
    std::lock_guard<std::mutex> guard(s_params.mutex);

    auto it = s_params.mctp_infos.find(controller_index);
    if (it == s_params.mctp_infos.end()) {
        return std::nullopt;
    }

    auto &info = it->second;
    return {std::make_tuple(info.phy_addr, info.vendor_id)};
}

l_mctp_infos::params l_mctp_infos::s_params;
}  // namespace sml
