-- 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 context = require 'mc.context'
local json = require 'cjson'
local m_enums = require 'types.enums'
local mc_initiator = require 'mc.initiator'
local log = require 'mc.logging'
local custom_messages = require 'messages.custom'
local customize_cfg = require 'customize_config'
local c_fructrl_obj_mgnt = require 'fructrl_obj_mgnt'

local config_manage = {}

local function get_op_initiator()
    local initiator
    local ctx = context.get_context_or_default()
    if ctx and not ctx:is_empty() then
        initiator = ctx:get_initiator()
    else
        initiator = mc_initiator.new('N/A', 'N/A', 'localhost')
    end
    return initiator
end

local function payload_group_import(fructrl, prop_vals)
    local import_map = {
        ['PowerRestorePolicy'] = {
            cb = fructrl.set_PowerOnStrategy,
            op_log = 'Set power restore policy failed'
        },
        ['PowerOffTimeout'] = {
            cb = fructrl.set_PowerOffTimeout,
            op_log = 'Set normal power off timeout failed'
        },
        ['PowerDelayMode'] = {
            cb = fructrl.set_PowerOnDelayMode,
            op_log = 'Set power up delay mode failed'
        },
        ['PowerDelayCount'] = {
            cb = fructrl.set_PowerOnDelaySeconds,
            op_log = 'Set power up delay time failed'
        },
        ['PowerOffTimeoutEN'] = {
            cb = fructrl.set_PowerOffTimeoutEN,
            op_log = 'Set power off timeout enable failed'
        },
        ['PwrButtonLock'] = {
            cb = fructrl.set_PanelPowerButtonEnabled,
            op_log = 'Set power button lock failed'
        }
    }
    for k, v in pairs(prop_vals) do
        if import_map[k] and v.Import then
            local ok
            if k == 'PwrButtonLock' then
                ok = import_map[k].cb(fructrl, not v.Value)
            elseif k == 'PowerDelayCount' then
                -- 导入的一个单位为100毫秒,资源树上单位是秒,需要除10
                ok = import_map[k].cb(fructrl, math.floor(v.Value) / 10)
            else
                ok = import_map[k].cb(fructrl, v.Value)
            end
            if ok ~= m_enums.RetValue.OK then
                log:operation(get_op_initiator(), 'fructrl', import_map[k].op_log)
                log:error('Import Payload [%s] failed', k)
                error(custom_messages.CollectingConfigurationErrorDesc(k))
            end
        elseif import_map[k] and not v.Import then
            log:notice('import %s failed,because import field is false', k)
        end
    end
end

-- 配置导入接口
function config_manage.import(ctx, datas, import_type)
    local fructrl_obj_mgnt = c_fructrl_obj_mgnt:get_instance()
    local button_evt = fructrl_obj_mgnt.button_evt

    local data = json.decode(datas)
    if not data or not data.ConfigData or type(data.ConfigData) ~= 'table' then
        log:error('import data [%s] is invalid.', datas)
        return
    end
    local fructrl
    for i, fructrl_obj in pairs(fructrl_obj_mgnt.host_obj) do
        if not fructrl_obj.fructrl or not fructrl_obj.fructrl.obj then
            goto continue
        end
        fructrl = fructrl_obj.fructrl
        -- 装备定制化
        if import_type == 'custom' then
            if data.ConfigData.CustomSettings then
                customize_cfg.on_import(fructrl, button_evt, ctx, data.ConfigData.CustomSettings)
            end
            goto continue
        end

        local import_map = {
            ['Payload'] = payload_group_import
        }
        for k, v in pairs(data.ConfigData) do
            repeat
                if not import_map[k] then
                    log:debug('There is no %s object to import', k)
                    break
                end
                import_map[k](fructrl, v)
                log:notice('import %s successfully(host%s)', k, i)
            until true
        end
        ::continue::
    end
end

-- 配置导出接口
function config_manage.export(ctx, export_type)
    local fructrl_obj_mgnt = c_fructrl_obj_mgnt:get_instance()
    local fructrl = fructrl_obj_mgnt.host_obj[1].fructrl
    local button_evt = fructrl_obj_mgnt.button_evt

    local payload_obj = {}
    local data = {}

    if export_type == 'custom' then  -- 装备定制化
        data.CustomSettings = customize_cfg.on_export(fructrl, button_evt, ctx)
        log:notice('Export payload customize config succsessfully')
        return json.encode({ConfigData = data})
    end
    data.PowerRestorePolicy = fructrl:get_PowerOnStrategy()
    log:notice('export PowerRestorePolicy successfully.')
    data.PowerOffTimeout = fructrl:get_PowerOffTimeout()
    log:notice('export PowerOffTimeout successfully.')
    data.PowerDelayMode = fructrl:get_PowerOnDelayMode()
    log:notice('export PowerDelayMode successfully.')
    -- 导出的单位为100毫秒,资源树上单位是秒,需要乘10
    data.PowerDelayCount = fructrl:get_PowerOnDelaySeconds() * 10
    log:notice('export PowerDelayCount successfully.')
    data.PowerOffTimeoutEN = fructrl:get_PowerOffTimeoutEN()
    log:notice('export PowerOffTimeoutEN successfully.')
    data.PwrButtonLock = not fructrl:get_PanelPowerButtonEnabled()
    log:notice('export PwrButtonLock successfully.')
    payload_obj.Payload = data

    log:notice('Export payload configuration successfully.')

    return json.encode({ConfigData = payload_obj})
end

return config_manage
