-- 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.

local collection_helper = require 'infrastructure.collection_helper'
local log_helper = {}
local log = require 'mc.logging'
local skynet = require 'skynet'

function log_helper.parser_collection(collection, cb, processor,...)
    collection_helper.for_each(collection, cb, processor, nil, ...)
end

function log_helper.dump_mdb_info(mdb_obj, fp, depth, key)
    local dump_msg = string.format('%s| %s:', string.rep('-', 2 * depth), key or mdb_obj.ObjectName)
    local info_str = string.format('%s\n', dump_msg)
    fp:write(info_str)
    if depth > 3 then
        return
    end
    if not mdb_obj.get_all_prop_names then
        return
    end
    local t_prop = mdb_obj:get_all_prop_names()
    local value
    local value_str
    for index, prop in pairs(t_prop) do
        value = mdb_obj:get_prop(prop)
        if type(value) ~= 'table' then
            value_str = tostring(value)
            info_str = string.format('%-40s | %-s\n', prop, value_str)
            fp:write(info_str)
        elseif prop ~= 'ObjectIdentifier' then
            skynet.sleep(10)
            log_helper.dump_mdb_info(value, fp, depth + 1, value.ObjectName or index)
        end
        skynet.sleep(10)
    end
    fp:write('\n\n\n')
end

function log_helper.get_conn_info(fp, conn, port_map)
    local dump_msg
    local info_str
    local bcu_index = conn.bcu_index or 1
    local head_msg
    for _, port in pairs(conn.ports) do
        -- 重复UBC口不重复打印
        if port_map[bcu_index] and port_map[bcu_index][port.name] then
            goto skip
        end
        if not port.target_unit_uid_record or string.len(port.target_unit_uid_record) == 0 then
            goto skip
        end
        head_msg = string.format('[BizTopoMonitor] BCU%s Port: name=%s, status=%s,', bcu_index, port.name,
            port.status_record)
        dump_msg = string.format('unit=[uid=%s, index=%s, port_id=%s]', port.target_unit_uid_record,
            port.target_unit_index_record, port.target_unit_port_id_record)
        info_str = string.format('%s %s\n',head_msg, dump_msg)
        fp:write(info_str)
        if not port_map[bcu_index] then
            port_map[bcu_index] = {}
        end
        port_map[bcu_index][port.name] = true
        skynet.sleep(10)
        ::skip::
    end
end

function log_helper.get_unit_config_info(fp, unit_config)
    local dump_msg
    local info_str
    local bcu_index
    local head_msg
    for _, config in pairs(unit_config.configs) do
        bcu_index = config.bcu_index or 1
        head_msg = string.format('[BizTopoMonitor] BCU%s Config: slot=%s-%s, status=%s,', bcu_index,
            unit_config:get_prop('SlotType'), unit_config:get_prop('SlotNumber'), unit_config:get_prop('Port1Status'))
        dump_msg = string.format('unit=[uid=%s, index=%s]', config.uid, config.index)
        info_str = string.format('%s %s\n', head_msg, dump_msg)
        fp:write(info_str)
        skynet.sleep(10)
    end
end

function log_helper.dump_cable_info(obj, fp, type, port_map)
    if not obj then
        log:error("obj is null")
        return
    end

    if type == 1 then
        log_helper.get_conn_info(fp, obj, port_map)
    elseif type == 2 then
        log_helper.get_unit_config_info(fp, obj)
    end
end

return log_helper