/* 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 <mutex>

#include "common/custom_log_handler.h"
#include "utils.h"
namespace Otel {
namespace Utils {

void get_attributes(lua_State *L, AttributeMap &attributes, int table_idx)
{
    if (!lua_istable(L, table_idx)) {
        luaL_error(L, "invalid parameter, get attributes failed");
    }
    lua_pushnil(L);
    while (lua_next(L, table_idx) != 0) {
        if (!lua_isstring(L, -2)) {
            luaL_error(L, "attribute key must be string");
        }
        const char *key = lua_tostring(L, -2);
        AttributeValue value = get_attribute_value(L, -1);
        attributes.emplace(key, value);
        lua_pop(L, 1);
    }
}

AttributeValue get_attribute_value(lua_State *L, int val_idx)
{
    AttributeValue value;
    int type = lua_type(L, val_idx);
    if (type == LUA_TNUMBER) {
        if (lua_isinteger(L, val_idx)) {
            value = static_cast<int64_t>(lua_tointeger(L, val_idx));
        } else {
            value = static_cast<double>(lua_tonumber(L, val_idx));
        }
    } else if (type == LUA_TSTRING) {
        size_t len = 0;
        const char* str = lua_tolstring(L, val_idx, &len);
        return AttributeValue(nostd::string_view(str, len));
    } else if (type == LUA_TBOOLEAN) {
        value = static_cast<bool>(lua_toboolean(L, val_idx));
    } else {
        luaL_error(L, "%s: unsupported attribute value type", __FUNCTION__);
    }

    return value;
}

void initialize_telemetry()
{
    static std::once_flag init_flag;
    std::call_once(init_flag, []() {
        // 设置日志模块
        auto cust_log_handler = new Common::CustomLogHandler{};
        cust_log_handler->SetModuleName(get_log_module_name());
        auto log_handler = nostd::shared_ptr<internal_log::LogHandler>(cust_log_handler);
        internal_log::GlobalLogHandler::SetLogHandler(log_handler);
        // 设置服务名
        std::string attr = "service.name=";
        attr.append(get_log_module_name());
        setenv("OTEL_RESOURCE_ATTRIBUTES", attr.c_str(), 1);
    });
}

} // namespace Utils
} // namespace Otel