-- 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 fw_mgmt = require 'general_hardware.client'
local log = require 'mc.logging'
local context = require 'mc.context'
local ini_parser = require 'mc.v2_persistence'

local common = {}

-- 从元素集合中查找指定元素
--     1.如果元素为基本数据类型，则传入元素值
--     2.如果元素为table类型，则传入条件匹配函数（匹配成功返回true）
function common.find(coll, val_or_match_func)
    -- table类型，按条件查找
    if type(val_or_match_func) == 'function' then
        for _, item in pairs(coll) do
            if val_or_match_func(item) == true then
                return item
            end
        end
    -- 简单类型
    else
        for i, item in pairs(coll) do
            if item == val_or_match_func then
                return i
            end
        end
    end
    return nil
end

-- skynet
local ok, skynet = pcall(require, 'skynet')
common.skynet = {
    fork = function (cb, ...)
        if ok then
            skynet.fork(cb, ...)
        end
    end,
    fork_once = function (cb, ...)
        if ok then
            skynet.fork_once(cb, ...)
        end
    end,
    sleep = function (timeout)
        if ok then
            skynet.sleep(timeout)
        end
    end
}

-- 将tbl中的元素以分隔符sep连接，并返回字符串
function common.join(tbl, sep)
    if type(tbl) ~= "table" then
        return ""
    end
    local result = ""
    for _, v in pairs(tbl) do
        result = result .. tostring(v) .. sep
    end
    return result
end

function common.init_client()
    local _, client = pcall(require, 'general_hardware.client')
    return client
end

common.client = common.init_client()

function common.get_package_info(file_path)
    local ret, package_info
    for _ = 1, 10 do
        ret, package_info = pcall(function ()
            return fw_mgmt:UpdateServiceUpdateServiceParseFirmwarePackage(context.new(), file_path)
        end)
        if ret and package_info then
            break
        end
    end
    if not ret then
        log:error('parse package failed, error:%s', package_info)
        return
    end
    return package_info
end

function common.remove_ele_by_position(list, position)
    for i, obj in pairs(list) do
        if obj.position == position then
            table.remove(list, i)
            break
        end
    end
end

function common.remove_ele_by_value(list, value)
    for i, v in pairs(list) do
        if v == value then
            table.remove(list, i)
            break
        end
    end
end

function common.is_support_multifirmware(path)
    if not path then
        log:error("Cfg path is nil")
        return false
    end

    local data = ini_parser.load_file(path)
    if not data.Firmware or not data.Firmware.FirmwareMode then
        log:info('Get FirmwareMode failed')
        return false
    end

    return data.Firmware.FirmwareMode == 'Multiple'
end

common.DEFAULT_SYSTEM_ID = 1

return common