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

-- Description: general_hardware装备定制化

local log = require 'mc.logging'
local factory = require 'factory'
local context = require 'mc.context'

local customize_cfg = {}

local CUSTOM_SEETINGS = "CustomSettings"
local CPLD_ACTIVE_CONF <const> = "BMCSet_CPLD_UpgradeActiveCondition"

local general_hardware_config_key = {
    ["DiskSlotCustomize"] = 'StartSlot',
    ["DiskSlotCustomizeId"] = 'StartSlot'
}

-- 设置硬盘背板中属性
local function set_config_value_to_resource_tree(resource_prop, value)
    local unit_manager = factory.get_obj("unit_manager")
    pcall(function ()
        unit_manager.hdd_backplanes[1]:set_prop(resource_prop, value)
    end)
end

local function customize_hddbackplane(config_table, customize_sign)
    if config_table['DiskSlotCustomize'] and config_table['DiskSlotCustomize']['Value'] == 'on' then
        customize_sign.StartSlot = true
        if config_table['DiskSlotCustomizeId'] and config_table['DiskSlotCustomizeId']['Value'] == 'Tencent' then
            set_config_value_to_resource_tree('StartSlot', 4)
            -- 0表示默认一个硬盘背板的情况,预留多硬盘背板场景
            customize_sign.StartSlotItems = {{0, 4}}
            log:notice("Import(DiskSlotCustomize, DiskSlotCustomizeId) customize(StartSlot) successfully," .. 
                "DiskSlotCustomize = on, DiskSlotCustomizeId = Tencent ,value is 4")
        else
            set_config_value_to_resource_tree('StartSlot', 0)
            customize_sign.StartSlotItems = {{0, 0}}
            log:notice("Import(DiskSlotCustomize, DiskSlotCustomizeId) customize(StartSlot) successfully," .. 
                "DiskSlotCustomize = '', DiskSlotCustomizeId = '' ,value is 0")
        end
    else
        customize_sign.StartSlot = false
        set_config_value_to_resource_tree('StartSlot', 0)
        customize_sign.StartSlotItems = {}
        log:notice("Import(DiskSlotCustomize, DiskSlotCustomizeId) customize(StartSlot) successfully," .. 
                "DiskSlotCustomize = '', DiskSlotCustomizeId = '' ,value is 0")
    end
end

local function customize_cpld_active_condition(config_table, customize_sign)
    local set_value = 'PowerOff'
    if config_table[CPLD_ACTIVE_CONF] then
        set_value = config_table[CPLD_ACTIVE_CONF]['Value']
    end
    log:notice('Import(BMCSet_CPLD_UpgradeActiveCondition) successfully, value is %s', set_value)
    if set_value ~= customize_sign.ActiveCondition then
        customize_sign.ActiveCondition = set_value
        log:operation(context:get_initiator(), 'general_hardware',
            'Set CPLD active condition to %s successfully', set_value)
    end
end

local function check_and_customize(config_table, db)
    local customize_sign = db.CustomizeSign({Id = 'customsize_sign'})

    customize_hddbackplane(config_table, customize_sign)
    customize_cpld_active_condition(config_table, customize_sign)
    customize_sign:save()
end

function customize_cfg.config_import_data(config_table, db)
    if not config_table then
        return
    end
    check_and_customize(config_table[CUSTOM_SEETINGS], db)
end

-- 从硬盘背板中获取属性
local function get_config_value_from_resource_tree(resource_prop)
    local unit_manager = factory.get_obj("unit_manager")
    local ok, value = pcall(function ()
        return unit_manager.hdd_backplanes[1]:get_prop(resource_prop)
    end)
    if not ok then
        log:error('get hdd_backplanes prop %s failed, ret: %s', resource_prop, value)
        return
    end
    return value
end

local function customize_prop(config_key, value)
    -- 是否开启了硬盘槽位定制，默认起始槽位为0
    if config_key == "DiskSlotCustomize" then
        return value == 0 and "" or "on"
    end
    if config_key == "DiskSlotCustomizeId" then
        return value == 4 and "Tencent" or ""
    end
end

-- 根据定制key值和对应资源树属性 填充 导出的table
local function fill_config(config_table, config_key, resource_prop)
    if not config_table[CUSTOM_SEETINGS] then
        config_table[CUSTOM_SEETINGS]= {}
    end
    config_table[CUSTOM_SEETINGS][config_key] = {}
    local resource_value = get_config_value_from_resource_tree(resource_prop)
    local custom_value = customize_prop(config_key, resource_value)
    config_table[CUSTOM_SEETINGS][config_key] = custom_value
    log:notice("export(%s) customize(%s) successfully, value is(%s : %s)",
                config_key,  resource_prop, resource_value, custom_value)
end

local function export_active_condition(config_table, db)
    local customize_sign = db.CustomizeSign({Id = 'customsize_sign'})
    local export_val = customize_sign and customize_sign.ActiveCondition or 'PowerOff'
    config_table[CUSTOM_SEETINGS][CPLD_ACTIVE_CONF] = export_val
    log:notice("export(BMCSet_CPLD_UpgradeActiveCondition) successfully, value is(%s)", export_val)
end

function customize_cfg.config_export_data(config_table, db)
    if not config_table then
        return
    end

    if not config_table[CUSTOM_SEETINGS] then
        config_table[CUSTOM_SEETINGS]= {}
    end

    for config_key, resource_prop in pairs(general_hardware_config_key) do
        fill_config(config_table, config_key, resource_prop)
    end

    export_active_condition(config_table, db)
end

return customize_cfg