-- 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 class = require 'mc.class'
local mod_service = require 'bios.service'
local bios_service = require 'service.bios_service'
local smbios_service = require 'service.smbios_service'
local bdf_service = require 'service.bdf_service'
local boot_options_service = require 'service.boot_options_service'
local secure_boot_options_service = require 'service.secure_boot_options_service'
local boot_service = require 'service.boot_service'
local file_service = require 'service.file_service'
local object_service = require 'service.object_service'
local bios_factory = require 'factory.bios_factory'
local ipmi_req = require 'bios.ipmi.ipmi'
local log = require 'mc.logging'
local bios_fw_signal = require 'interface.signal'
local pro_global = require 'macros.property_global'
local object_manage = require 'mc.mdb.object_manage'
local reboot_manage = require 'mc.mdb.micro_component.reboot'
local prop_def = require 'macros.property_def'
local msg = require 'bios.ipmi.ipmi_message'
local kmc_client = require 'service.kmc_client'
local upgrade_service = require 'service.upgrade_service'
local pfr_service = require 'service.pfr_service'
local peripherals_device = require 'service.peripherals_device'
local ipmi = require 'ipmi'
local comp_code = ipmi.types.Cc
local base_messages = require 'messages.base'
local import_export_eng = require 'handler.export_import_engine'
local mdb_config_manage = require 'mc.mdb.micro_component.config_manage'
local mc_admin = require 'mc.mc_admin'
local utils_core = require 'utils.core'
local imu_cmd = require 'infrastructure.imu'
local intf_debug = require 'mc.mdb.micro_component.debug'
local log_collector = require 'service.log_collector'
local alarm_manager = require 'domain.alarm.alarm_manager'
local fructl_handler = require 'infrastructure.fructl'
local retirement = require 'handler.retirement_handler'
local peripherals_ipmi = require 'ipmi.peripherals_ipmi'
local privilege_check = require 'infrastructure.privilege_check'
local skynet = require 'skynet'
local app_bios = class(mod_service)
local c_multihost_card_config = require 'pojo.multihost_card_config'
local defs = require 'domain.alarm.defs'
local boot_def = require "macros.boot_def"

function app_bios:add_manual_obj(object)
    local system_id = object:get_system_id()
    self.bios_service:add_object(object)
    self.boot_service:add_object(system_id, self:CreateBootOptions(system_id, function(obj)
        obj.ObjectName = 'BootOptions_' .. system_id
    end))
    self.smbios_service:add_obj(system_id, self:CreateSmBios(system_id, function(obj)
        obj.ObjectName = 'SmBios_' .. system_id
        obj.SystemId = system_id
    end))
    self.boot_options_service:add_object({SystemId = system_id})
    self.upgrade_service:add_snapshot(system_id, self:CreateBiosUpgradeService(system_id, function(obj)
        obj.ObjectName = 'BiosUpgradeService_' .. system_id
    end))
    self.pfr_service:add_gold_package(system_id)
end

function app_bios:enable_multihost()
    self.upgrade_service:enable_multihost()
    self.bios_service:enable_multihost()
    self.smbios_service:enable_multihost()
end

function app_bios:on_add_object(class_name, object, position)
    local switch = {
        ['Bios'] = function()
            if object.Slot == 0 then
                self:add_manual_obj(object)
                return
            end
            -- 主Bios上树，从Bios不上树
            if object.Slot % 2 == 1 then
                self:add_manual_obj(object)
            end
            self:enable_multihost()
        end,
        ['SecureBootOptions'] = function()
            local system_id = object:get_system_id()
            if object.Slot == 0 then
                self.secure_boot_options_service:add_object(system_id, object)
                return
            end
            -- 主Bios上树，从Bios不上树
            if object.Slot % 2 == 1 then
                self.secure_boot_options_service:add_object(system_id, object)
            end
        end,
        ['SPIChannel'] = function()
            self.bios_service:set_spi_channel(object)
        end,
        ['SystemFirmwareProgress'] = function()
            object:register_mdb_objects()
            self.peripherals_device:add_object(object)
        end,
        ['BIOSIPMIChannelConfig'] = function ()
            local imu_obj = imu_cmd.get_instance(self.bus)
            imu_obj:add_instances(object)
        end,
        ['SPIRate'] = function ()
            self.upgrade_service:config_spi_rate(object)
        end,
        ['BIOSMultihostConfig'] = function ()
            local config_obj = c_multihost_card_config.new(object)
            self.bios_service:set_multihost_card_config(config_obj.configs)
        end,
        ['CPUDie'] = function ()
            self.bios_service:set_cpu_die(object)
        end
    }

    if switch[class_name] then
        switch[class_name]()
        log:info('[app_bios] Add object, object_name: %s', object.ObjectName)
    end
end

function app_bios:on_add_object_extra(class_name, object, position)
    local switch = {
        ['BiosFirmwareCustomConfig'] = function()
            pro_global.G_BIOS_FIRMWARE_CUSTOM_CONFIG = object.CMSSignEnable
        end,
        ['MemorySilk'] = function()
            local system_id = object:get_system_id()
            self.bios_service:add_multihost_memsilk_config(system_id, object)
        end
    }

    if switch[class_name] then
        switch[class_name]()
        log:info('[app_bios] Add object, object_name: %s', object.ObjectName)
    end
end

function app_bios:set_dft_mode()
    if self.upgrade_service then
        self.upgrade_service:set_dft_mode()
        log:notice('[bios]set dft mode success')
        if self.bios_service then
            self.bios_service:notify_dft_mode()
        end
        return true
    end
    return false
end

function app_bios:ctor()
    self.bdf_service = bdf_service.new()
    bios_factory.register_bean('bdf_service', self.bdf_service)
end

function app_bios:check_dependencies()
    local admin = mc_admin.new()
    admin:parse_dependency(utils_core.getcwd() .. '/mds/service.json')
    admin:check_dependency(self.bus)
end

function app_bios:get_system_id(path)
    return tonumber(string.match(path, '/bmc/kepler/Systems/(%d+)'))
end

function app_bios:register_boot_rpc_methods()
    self:ImplBootOptionsBootOptionsSetBootOrder(function(obj, ctx, ...)
        return self:SetBootOrder(ctx, obj, ...)
    end)
    self:ImplBootOptionsBootOptionsSetStartOption(function(obj, ctx, ...)
        return self:SetStartOption(ctx, obj, ...)
    end)
    self:ImplBootOptionsBootOptionsSetStartOptionFlag(function(obj, ctx, ...)
        return self:SetStartOptionFlag(ctx, obj, ...)
    end)
    self:ImplBootOptionsBootOptionsSetBootMode(function(obj, ctx, ...)
        return self:SetBootMode(ctx, obj, ...)
    end)

    self:ImplBootOptionsBootOptionsShieldIpmiModifyBootModeSupport(function(obj, ctx, ...)
        return self:SetBootModeSw(ctx, obj, ...)
    end)
    self:ImplBootOptionsBootOptionsImportCertificate(function(obj, ctx, ...)
        return self:ImportBootCertificate(ctx, obj, ...)
    end)
    self:ImplBootOptionsBootOptionsImportCrl(function(obj, ctx, ...)
        return self:ImportBootCrl(ctx, obj, ...)
    end)
    self:ImplBootOptionsBootOptionsResetCertificate(function(obj, ctx, ...)
        return self:ResetBootCertificate(ctx, obj, ...)
    end)
    self:ImplBootOptionsBootOptionsResetCrl(function(obj, ctx, ...)
        return self:ResetBootCrl(ctx, obj, ...)
    end)
    self:ImplBootOptionsBootOptionsGetCertificate(function(obj, ctx, ...)
        return self:GetBootCertificate(ctx, obj, ...)
    end)
    self:ImplSecureBootOptionsSecureBootOptionsImportCertificate(function(obj, ctx, ...)
        return self:ImportSecureBootCertificate(ctx, obj, ...)
    end)
    self:ImplSecureBootOptionsSecureBootOptionsResetCertificate(function(obj, ctx, ...)
        return self:ResetSecureBootCertificate(ctx, obj, ...)
    end)
    self:ImplSecureBootOptionsSecureBootOptionsGetCertificate(function(obj, ctx, ...)
        return self:GetSecureBootCertificate(ctx, obj, ...)
    end)
end

function app_bios:register_bios_rpc_methods()
    self:ImplBiosBiosGetCurrentValueSetting(function(obj, ctx, ...)
        return self:GetCurrentValueSetting(obj, ...)
    end)

    self:ImplBiosBiosClearCmos(function(obj, ctx, ...)
        return self:ClearCmos(ctx, obj, ...)
    end)

    self:ImplBiosBiosResetSetupConfig(function(obj, ctx, ...)
        return self:ResetBios(ctx, obj, ...)
    end)

    self:ImplBiosBiosRemoveCachedSettings(function(obj, ctx, ...)
        return self:remove_cache_setting(ctx, obj, ...)
    end)

    self:ImplBiosBiosChangePassword(function(obj, ctx, ...)
        return self:ResetBiosPassword(ctx, obj, ...)
    end)

    self:ImplBiosUpgradeServiceBiosUpgradeServiceExportBiosFirmware(function(obj, ctx, ...)
        return self:ExportBiosFirmware(ctx, obj, ...)
    end)

    self:ImplBiosBiosImportBiosSetup(function(obj, ctx, ...)
        return self:ImportBiosSetup(ctx, obj, ...)
    end)

    self:ImplBiosBiosExportBiosSetup(function(obj, ctx, ...)
        return self:ExportBiosConfig(ctx, obj, ...)
    end)

    self:ImplBiosUpgradeServiceBiosUpgradeServiceActivateFirmware(function(obj, ctx, ...)
        return self:ActivateFirmware(ctx, ...)
    end)

    self:ImplBiosBiosSetBiosConfigActiveMode(function(obj, ctx, ...)
        self:SetBiosConfigActiveMode(ctx, obj, ...)
    end)

    -- 导入导出注册
    mdb_config_manage.on_import(function(ctx, config_data, import_type)
        import_export_eng.import(ctx, config_data, import_type)
    end)
    mdb_config_manage.on_export(function(ctx, export_type)
        return import_export_eng.export(ctx, export_type)
    end)
end

function app_bios:register_retirement_rpc_methods()
    self:ImplBiosRetirementDataWipe(function(obj, ctx, ...)
        return self:DataWipe(ctx, obj)
    end)
    self:ImplBiosRetirementGetReport(function (obj, ctx, ...)
        return self:GetDataWipeReport(obj, ctx)
    end)
end

function app_bios:init_service()
    self.name = 'bios'
    self.dft_mode = false
    self.upgrade_service = upgrade_service.new(self.db, self.bus)
    bios_factory.register_bean('upgrade_service', self.upgrade_service)

    self.signal = bios_fw_signal.init(self.bus, self.db)
    self.bios_service = bios_service.new(self.bus, self.db)
    self.boot_options_service = boot_options_service.new(self.db)
    self.secure_boot_options_service = secure_boot_options_service.new(self.db)
    self.boot_service = boot_service.new(self.db)
    self.smbios_service = smbios_service.new(self.db)
    self.peripherals_device = peripherals_device.new(self.bus)

    bios_factory.register_bean('bios_service', self.bios_service)
    bios_factory.register_bean('boot_options_service', self.boot_options_service)
    bios_factory.register_bean('secure_boot_options_service', self.secure_boot_options_service)
    bios_factory.register_bean('boot_service', self.boot_service)
    bios_factory.register_bean('smbios_service', self.smbios_service)
    bios_factory.register_bean('peripherals_device', self.peripherals_device)
    bios_factory.register_db_connection('db', self.db)

    self.object_service = object_service.new(self.bus)
    bios_factory.register_bean('object_service', self.object_service)

    self.key_mgmt_client = kmc_client.new(self.bus, self.name)
    bios_factory.register_bean('kmc_service', self.key_mgmt_client)

    self.pfr_service = pfr_service.new(self.db)
    self.upgrade_service:cache_hpms_after_activate()
    bios_factory.register_bean('pfr_service', self.pfr_service)
end

local function register_poweron_delay_ipmi_cmd(self)
    self:register_ipmi_cmd(ipmi_req.GetBootOptionPowerOnDelay0, app_bios.bios_get_boot_option_power_on_delay0)
    self:register_ipmi_cmd(ipmi_req.GetBootOptionPowerOnDelay1, app_bios.bios_get_boot_option_power_on_delay1)
    self:register_ipmi_cmd(ipmi_req.SetBootOptionPowerOnDelay0, app_bios.bios_set_boot_option_power_on_delay0)
    self:register_ipmi_cmd(ipmi_req.SetBootOptionPowerOnDelay1, app_bios.bios_set_boot_option_power_on_delay1)
end

local function register_boot_info_ipmi_cmd(self)
    self:register_ipmi_cmd(ipmi_req.GetBootOption, app_bios.bios_get_boot_option)
    self:register_ipmi_cmd(ipmi_req.SetBootOption, app_bios.bios_set_boot_option)
    self:register_ipmi_cmd(ipmi_req.GetBiosBootInfo, app_bios.get_bios_boot_info)
    self:register_ipmi_cmd(ipmi_req.SetBiosBootInfo, app_bios.set_bios_boot_info)
end

function app_bios:register_ipmi()
    -- 设置/读取缓存BIOS包的升级模式
    self:register_ipmi_cmd(ipmi_req.SetCachedBiosUpgradeMode, app_bios.set_cached_bios_upgrade_mode)
    self:register_ipmi_cmd(ipmi_req.GetCachedBiosUpgradeMode, app_bios.get_cached_bios_upgrade_mode)
    self:register_ipmi_cmd(ipmi_req.WriteSmbiosData, app_bios.write_smbios_data)
    self:register_ipmi_cmd(ipmi_req.SetBiosVersion, app_bios.set_bios_version)
    self:register_ipmi_cmd(ipmi_req.WriteFileToBmc, app_bios.bios_write_file_to_bmc)
    self:register_ipmi_cmd(ipmi_req.WritePcieCardBdfToBmc, app_bios.bios_write_pcie_card_bdf_to_bmc)
    self:register_ipmi_cmd(ipmi_req.WritePcieDiskBdfToBmc, app_bios.bios_write_pcie_disk_bdf_to_bmc)
    self:register_ipmi_cmd(ipmi_req.WriteOcpCardBdfToBmc, app_bios.bios_write_ocp_card_bdf_to_bmc)
    self:register_ipmi_cmd(ipmi_req.ReadFileFromBmc, app_bios.bios_read_file_from_bmc)
    self:register_ipmi_cmd(ipmi_req.GetFileChanged, app_bios.bios_get_file_changed)

    register_poweron_delay_ipmi_cmd(self)
    register_boot_info_ipmi_cmd(self)

    self:register_ipmi_cmd(ipmi_req.GetSmBiosInfo, app_bios.get_smbios_info)
    self:register_ipmi_cmd(ipmi_req.SetSmBiosInfo, app_bios.set_smbios_info)
    self:register_ipmi_cmd(ipmi_req.UpdateBiosPassword, app_bios.update_bios_password)
    self:register_ipmi_cmd(ipmi_req.UpdateBiosStatus, app_bios.update_bios_status)
    self:register_ipmi_cmd(ipmi_req.GetBiosGoldValid, app_bios.get_bios_gold_valid)
    -- 启动信息ipmi获取命令
    self:register_ipmi_cmd(ipmi_req.GetProgressSystemInfo, app_bios.ipmi_get_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.GetSystemFirmwareVersion,
        app_bios.ipmi_get_system_firware_version)
    self:register_ipmi_cmd(ipmi_req.GetSystemName, app_bios.ipmi_get_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.GetPrimaryOperatingSystemName,
        app_bios.ipmi_get_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.GetOperatingSystemName, app_bios.ipmi_get_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.GetChannelInfo, app_bios.ipmi_get_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.GetBridgeSystemInfo, app_bios.ipmi_get_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.GetDeviceSystemInfo, app_bios.ipmi_get_system_info_parameters)

    -- 启动信息ipmi设置命令
    self:register_ipmi_cmd(ipmi_req.SetProgressSystemInfo, app_bios.ipmi_set_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.SetSystemFirmwareVersion,
        app_bios.ipmi_set_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.SetSystemName, app_bios.ipmi_set_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.SetPrimaryOperatingSystemName,
        app_bios.ipmi_set_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.SetOperatingSystemName, app_bios.ipmi_set_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.SetChannelInfo, app_bios.ipmi_set_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.SetBridgeSystemInfo, app_bios.ipmi_set_system_info_parameters)
    self:register_ipmi_cmd(ipmi_req.SetDeviceSystemInfo, app_bios.ipmi_set_system_info_parameters)

    self:register_ipmi_cmd(ipmi_req.UpdatePostStatus, app_bios.update_post_status)
    self:register_ipmi_cmd(ipmi_req.SetFileChanged, app_bios.bios_set_file_changed)
    self:register_ipmi_cmd(ipmi_req.AddBiosLogEntry, app_bios.add_bios_log_entry)

    self:register_ipmi_cmd(ipmi_req.SetCertificateDeassertion, app_bios.set_certificate_deassertion)
    self:register_ipmi_cmd(ipmi_req.SetCertificateAssertion, app_bios.set_certificate_assertion)
    self:register_ipmi_cmd(ipmi_req.ReportAlarm, app_bios.report_alarm)
    self:register_ipmi_cmd(ipmi_req.ReportVRStatus, app_bios.report_vr_status)
    self:register_ipmi_cmd(ipmi_req.SetTeeOSVersion, app_bios.set_teeos_version)
    self:register_ipmi_cmd(ipmi_req.SetVedioStatus, peripherals_ipmi.set_device_status_video)
    self:register_ipmi_cmd(ipmi_req.SetKbcStatus, peripherals_ipmi.set_device_status_kbc)
    self:register_ipmi_cmd(ipmi_req.SetBiosConfigItem, app_bios.set_bios_config_item)
end

function app_bios:register_object_callback()
    object_manage.on_add_object(self.bus, function(class_name, object, position)
        self:on_add_object(class_name, object, position)
        self:on_add_object_extra(class_name, object, position)
    end, function()
        return false
    end)
    object_manage.on_delete_object(self.bus, function(class_name, object, position)
    end)
    object_manage.on_add_object_complete(self.bus, function(position)
    end)
    object_manage.on_delete_object_complete(self.bus, function(position)
    end)
end

-- 往导入导出引擎注册信息
function app_bios:import_export_engine_register()
    import_export_eng.register_config_dealer('BootOption', self.boot_service)
    import_export_eng.register_config_dealer('SmBios', self.smbios_service)
    import_export_eng.register_config_dealer('UpdateService', self.upgrade_service)
end

function app_bios:init_log_dump()
    intf_debug.on_dump(function(...)
        log_collector.log_dump(...)
    end)
end

function app_bios:init_domain()
    alarm_manager.new(self.local_db)
    log:notice('[bios]init doamin success')
end

function app_bios:init_infrastructure()
    imu_cmd.new(self.bus)
    log:notice('[bios]init infrastructure success')
end

function app_bios:init_insure_action()
    local ok, err = pcall(function()
        local power_status = fructl_handler.get_power_status()
        if power_status == 'OFF' then
            local pfr_ser = bios_factory.get_service('pfr_service')
            pfr_ser:try_unlock_forever()
            local alarm_mgr = alarm_manager.get_instance()
            alarm_mgr:recover()
        end
    end)
    if not ok then
        log:error('[bios]power status is off, execute insure action failed, err: %s', err)
    else
        log:notice('[bios]power status is off, execute insure action successfully')
    end
end

function app_bios:init()
    log:notice('[bios]super init start')
    app_bios.super.init(self)
    log:notice('[bios]check dependencies start')
    self:check_dependencies()
    log:notice('[bios]init finish')
    skynet.fork_once(function()
        log:notice('[bios]fork init start')
        self:init_service()
        self:register_reboot_methods()
        self:register_bios_rpc_methods()
        self:register_boot_rpc_methods()
        self:register_retirement_rpc_methods()
        self:register_ipmi()
        self:register_object_callback()
        self:import_export_engine_register()
        self:init_log_dump()
        self:init_infrastructure()
        self:init_domain()
        self:init_insure_action()
        log:notice('[bios]fork init end')
    end)
end

function app_bios:on_reboot_prepare()
    log:info('[bios] reboot prepare')
end

function app_bios:on_reboot_cancel()
    log:info('[bios] reboot cancel')
end

function app_bios:on_reboot_action()
    log:info('[bios] reboot action')
end

function app_bios:can_reboot()
    local ok, res = pcall(function()
        if self.upgrade_service.state_machine and self.upgrade_service.state_machine:get_state() ~= "UPGRADE_READY" then
            log:error('[bios]reboot bmc failed, cause bios upgrade is progress ,please wait')
            return -1
        end
        log:notice('[bios]bios no upgrade, can reboot bmc')
        return 0
    end)
    if ok then
        return res
    end
    return 0
end

function app_bios:register_reboot_methods()
    -- 注册平滑重启回调函数
    -- Prepare准备重启回调
    reboot_manage.on_prepare(function()
        self:on_reboot_prepare()
        return self:can_reboot()
    end)
    -- Action执行重启回调
    reboot_manage.on_action(function()
        self:on_reboot_action()
        return 0
    end)
    -- Cancel取消重启回调
    reboot_manage.on_cancel(function()
        self:on_reboot_cancel()
    end)
end

function app_bios.set_bios_config_item(req, ctx)
    local file_ser = file_service.new()
    return file_ser:set_bios_config_item(req, ctx, 'Setting')
end

function app_bios.write_smbios_data(req, ctx)
    local smbios_ser = bios_factory.get_service('smbios_service')
    if not smbios_ser then
        log:error('smbios_service is nil')
        return
    end

    return smbios_ser:write_smbios_data(req, ctx)
end

function app_bios.bios_write_file_to_bmc(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('bios_service is nil')
        return
    end

    return bios_ser:bios_write_file_to_bmc(req, ctx)
end

function app_bios.bios_write_pcie_card_bdf_to_bmc(req, ctx)
    local bdf_ser = bios_factory.get_service('bdf_service')
    if not bdf_ser then
        log:error('[bios] bdf_ser is nil')
        return
    end

    req.ParameterSelector = prop_def.BIOS_IPMI_CMD_PCIECARD
    local err_code, maun_id = bdf_ser:bios_write_bdf_to_bmc(req, ctx)
    return msg.WritePcieCardBdfToBmcRsp.new(err_code, maun_id)
end

function app_bios.bios_write_pcie_disk_bdf_to_bmc(req, ctx)
    local bdf_ser = bios_factory.get_service('bdf_service')
    if not bdf_ser then
        log:error('[bios] bdf_ser is nil')
        return
    end

    req.ParameterSelector = prop_def.BIOS_IPMI_CMD_PCIEDISK
    local err_code, maun_id = bdf_ser:bios_write_bdf_to_bmc(req, ctx)
    return msg.WritePcieDiskBdfToBmcRsp.new(err_code, maun_id)
end

function app_bios.bios_write_ocp_card_bdf_to_bmc(req, ctx)
    local bdf_ser = bios_factory.get_service('bdf_service')
    if not bdf_ser then
        log:error('[bios] bdf_ser is nil')
        return
    end

    req.ParameterSelector = prop_def.BIOS_IPMI_CMD_OCPCARD
    local err_code, maun_id = bdf_ser:bios_write_bdf_to_bmc(req, ctx)
    return msg.WriteOcpCardBdfToBmcRsp.new(err_code, maun_id)
end

function app_bios.bios_read_file_from_bmc(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('bios_service is nil')
        return
    end

    return bios_ser:bios_read_file_from_bmc(req, ctx)
end

function app_bios.bios_get_file_changed(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('bios_service is nil')
        return
    end

    return bios_ser:bios_get_file_changed(req, ctx)
end

function app_bios.set_bios_version(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('bios_service is nil')
        return
    end

    return bios_ser:update_bios_version(req, ctx)
end

function app_bios.set_teeos_version(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('bios_service is nil')
        return
    end

    return bios_ser:update_teeos_version(req, ctx)
end

function app_bios.bios_get_boot_option(req, ctx)
    local boot_option_ser = bios_factory.get_service('boot_options_service')
    if not boot_option_ser then
        log:error('boot_option_service is nil')
        return
    end

    return boot_option_ser:get_boot_option_data(req, ctx)
end

function app_bios.bios_get_boot_option_power_on_delay0(req, ctx)
    req.BootOptionSelector = 0x65
    return app_bios.bios_get_boot_option(req, ctx)
end

function app_bios.bios_get_boot_option_power_on_delay1(req, ctx)
    req.BootOptionSelector = 0xE5
    return app_bios.bios_get_boot_option(req, ctx)
end

function app_bios.bios_set_boot_option(req, ctx)
    local boot_option_ser = bios_factory.get_service('boot_options_service')
    if not boot_option_ser then
        log:error('boot_option_service is nil')
        return
    end

    return boot_option_ser:set_boot_option_data(req, ctx)
end

function app_bios.bios_set_boot_option_power_on_delay0(req, ctx)
    req.BootOptionSelector = 0x65
    return app_bios.bios_set_boot_option(req, ctx)
end

function app_bios.bios_set_boot_option_power_on_delay1(req, ctx)
    req.BootOptionSelector = 0xE5
    return app_bios.bios_set_boot_option(req, ctx)
end

function app_bios.get_smbios_info(req, ctx)
    local smbios_ser = bios_factory.get_service('smbios_service')
    if not smbios_ser then
        log:error('smbios_service is nil')
        return
    end

    return smbios_ser:get_smbios_info(req, ctx)
end

function app_bios.set_smbios_info(req, ctx)
    local smbios_ser = bios_factory.get_service('smbios_service')
    if not smbios_ser then
        log:error('smbios_service is nil')
        return
    end

    return smbios_ser:set_smbios_info(req, ctx)
end

function app_bios.get_bios_boot_info(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('[bios]get_bios_boot_info: bios_service is nil.')
        return
    end

    return bios_ser:get_bios_boot_info(req, ctx)
end

function app_bios.set_bios_boot_info(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('[bios]set_bios_boot_info: bios_service is nil.')
        return
    end

    return bios_ser:set_bios_boot_info(req, ctx)
end

function app_bios.get_bios_gold_valid(req, ctx)
    local pfr_ser = bios_factory.get_service('pfr_service')
    if not pfr_ser then
        log:error('[bios]get_bios_gold_valid: pfr_service is nil.')
        return
    end

    return pfr_ser:get_bios_gold_valid(req, ctx)
end

function app_bios.ipmi_get_system_firware_version(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('bios_service is nil')
        return
    end

    return bios_ser:get_system_firware_version(req, ctx)
end

function app_bios.ipmi_get_system_info_parameters(req, ctx)
    return comp_code.DataNotAvailable, prop_def.ParameterRevision, ''
end

function app_bios.ipmi_set_system_info_parameters(req, ctx)
    return comp_code.DataNotAvailable
end

function app_bios.update_post_status(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    return bios_ser:update_post_status(req, ctx)
end

function app_bios.bios_set_file_changed(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    return bios_ser:bios_set_file_changed(req, ctx)
end

function app_bios.report_alarm(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    return bios_ser:report_alarm(defs.DeviceId.PSU, req, ctx)
end

function app_bios.report_vr_status(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    return bios_ser:report_alarm(defs.DeviceId.VR, req, ctx)
end

function app_bios.add_bios_log_entry(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    return bios_ser:add_bios_log_entry(req, ctx)
end

function app_bios.set_certificate_deassertion(req, ctx)
    local boot_ser = bios_factory.get_service('secure_boot_options_service')
    req.Status = 0x00
    return boot_ser:set_certificate_satus(req, ctx)
end

function app_bios.set_certificate_assertion(req, ctx)
    local boot_ser = bios_factory.get_service('secure_boot_options_service')
    req.Status = 0x01
    return boot_ser:set_certificate_satus(req, ctx)
end

function app_bios.update_bios_password(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('[bios]update_bios_password: bios_service is nil.')
        return
    end

    return bios_ser:update_bios_password(req, ctx)
end

function app_bios.update_bios_status(req, ctx)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('[bios]update_bios_status: bios_service is nil.')
        return
    end

    return bios_ser:update_bios_status(req, ctx)
end

function app_bios.set_cached_bios_upgrade_mode(req, ctx)
    local mode = req['UpgradeMode']
    local bios_upgrade_service = bios_factory.get_service('upgrade_service')
    return bios_upgrade_service:ipmi_set_cached_bios_upgrade_mode(ctx, mode)
end

function app_bios.get_cached_bios_upgrade_mode(req, ctx)
    local bios_upgrade_service = bios_factory.get_service('upgrade_service')
    return bios_upgrade_service:ipmi_get_cached_bios_upgrade_mode()
end

function app_bios:SetBootOrder(ctx, obj, BootOrderJson)
    return self.boot_service:set_boot_priority(ctx, BootOrderJson, self:get_system_id(obj.path))
end

function app_bios:SetStartOption(ctx, obj, StartOption)
    local system_id = self:get_system_id(obj.path)
    local boot_options_ser = bios_factory.get_service('boot_options_service')
    if boot_options_ser:auto_clear_valid(ctx) and system_id == 1 then
        log:notice('auto clear valid is true, start to create set option countdown task')
        boot_options_ser:create_option_countdown_task(ctx, StartOption)
        pro_global.G_SET_BIOS_OPTION = boot_def.TaskFlag.LastRpc
        return prop_def.RESPONSE_OK
    else
        log:notice('auto clear valid is false, set start option')
        return self.boot_options_service:set_start_option_ext(ctx, StartOption, system_id)
    end
end

function app_bios:SetStartOptionFlag(ctx, obj, StartOptionFlag)
    local system_id = self:get_system_id(obj.path)
    local boot_options_ser = bios_factory.get_service('boot_options_service')
    if boot_options_ser:auto_clear_valid(ctx) and system_id == 1 then
        log:notice('auto clear valid is true, start to create set effctive times countdown task')
        boot_options_ser:create_times_countdown_task(ctx, StartOptionFlag)
        pro_global.G_SET_BIOS_OPTION_FLAG = boot_def.TaskFlag.LastRpc
        return prop_def.RESPONSE_OK
    else
        log:notice('auto clear valid is false, set start option flag')
        return self.boot_options_service:set_start_option_flag_ext(ctx, StartOptionFlag, system_id)
    end
end

function app_bios:GetCurrentValueSetting(obj, req)
    return self.bios_service:get_current_value_setting(self:get_system_id(obj.path), req)
end

function app_bios:ExportBiosConfig(ctx, obj, file_type)
    local file_ser = file_service.new()
    return file_ser:export_bios_config(file_type, self:get_system_id(obj.path))
end

function app_bios:ActivateFirmware(ctx, activate_modes)
    self.upgrade_service:activate_components(ctx, activate_modes)
end

function app_bios:SetBiosConfigActiveMode(ctx, obj, BiosConfigActiveMode)
    return self.bios_service:set_prop('BiosConfigActiveMode',
        BiosConfigActiveMode, self:get_system_id(obj.path))
end

function app_bios:SetBootMode(ctx, obj, mode)
    local boot_option_ser = self.boot_options_service
    if not boot_option_ser then
        log:error('boot_option_service is nil')
        error(base_messages.InternalError())
    end

    return boot_option_ser:set_boot_mode_ext(ctx, mode, self:get_system_id(obj.path))
end

function app_bios:SetBootModeSw(ctx, obj, mode_switch)
    local boot_ser = self.boot_service
    if not boot_ser then
        log:error('[bios]SetBootModeSw: boot_service is nil')
        error(base_messages.InternalError())
    end
    -- 此处not mode_switch为是否屏蔽启动模式开关
    return boot_ser:set_boot_mode_switch(ctx, not mode_switch, self:get_system_id(obj.path))
end

function app_bios:check_privilege(ctx)
    local res = privilege_check.check(ctx)
    if not res then
        error(base_messages.InsufficientPrivilege())
    end
end

function app_bios:remove_cache_setting(ctx, obj)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('[bios]remove_cache_setting: bios_service is nil')
        return
    end
    self:check_privilege(ctx)
    return bios_ser:remove_cache_setting(ctx, self:get_system_id(obj.path))
end

function app_bios:ResetBios(ctx, obj)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('[bios]ResetBios: bios_service is nil')
        return
    end
    self:check_privilege(ctx)
    return bios_ser:reset_bios(ctx, self:get_system_id(obj.path))
end

function app_bios:ClearCmos(ctx, obj)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('[bios]ClearCmos: bios_service is nil')
        return
    end
    self:check_privilege(ctx)

    local system_id = self:get_system_id(obj.path)

    local boot_options_ser = bios_factory.get_service('boot_options_service')
    if boot_options_ser:auto_clear_valid(ctx) and system_id == 1 then
        log:notice('auto clear valid is true, start to create clear cmos countdown task')
        bios_ser:create_countdown_task(ctx)
        return prop_def.RESPONSE_OK
    else
        log:notice('auto clear valid is false, clear cmos')
        return bios_ser:clear_cmos(ctx, system_id)
    end
end

function app_bios:ImportBiosSetup(ctx, obj, file_type, content)
    self:check_privilege(ctx)
    local file_ser = file_service.new()
    return file_ser:import_json(ctx, file_type, content, self:get_system_id(obj.path))
end

function app_bios:ResetBiosPassword(ctx, obj, type, old_pwd, new_pwd)
    local bios_ser = bios_factory.get_service('bios_service')
    if not bios_ser then
        log:error('[bios]ResetBiosPassword: bios_service is nil')
        return
    end
    return bios_ser:reset_bios_password(ctx, type, old_pwd, new_pwd, self:get_system_id(obj.path))
end

function app_bios:ExportBiosFirmware(ctx, obj)
    local upgrade_ser = bios_factory.get_service('upgrade_service')
    if not upgrade_ser then
        log:error('[bios]ExportBiosFirmware: bios_service is nil')
        return
    end
    return upgrade_ser:export_bios_firmware(ctx, obj.path)
end

function app_bios:ImportBootCertificate(ctx, obj, cert_string, cert_type)
    local boot_options_ser = bios_factory.get_service('boot_options_service')
    if not boot_options_ser then
        log:error('[bios]import boot certificate: boot option service is nil')
        return
    end
    return boot_options_ser:import_boot_certificate(ctx, cert_string, cert_type, self:get_system_id(obj.path))
end

function app_bios:ResetBootCertificate(ctx, obj, reset_type)
    local boot_options_ser = bios_factory.get_service('boot_options_service')
    if not boot_options_ser then
        log:error('[bios]reset boot certificate: boot option service is nil')
        return
    end
    return boot_options_ser:reset_boot_certificate(ctx, reset_type, self:get_system_id(obj.path))
end

function app_bios:ImportBootCrl(ctx, obj, cert_string, cert_type)
    local boot_options_ser = bios_factory.get_service('boot_options_service')
    if not boot_options_ser then
        log:error('[bios]import crl: boot option service is nil')
        return
    end
    return boot_options_ser:import_boot_crl(ctx, cert_string, cert_type, self:get_system_id(obj.path))
end

function app_bios:ResetBootCrl(ctx, obj, reset_type)
    local boot_options_ser = bios_factory.get_service('boot_options_service')
    if not boot_options_ser then
        log:error('[bios]reset crl: boot option service is nil')
        return
    end
    return boot_options_ser:reset_boot_crl(ctx, reset_type, self:get_system_id(obj.path))
end

function app_bios:GetBootCertificate(ctx, obj)
    local boot_options_ser = bios_factory.get_service('boot_options_service')
    if not boot_options_ser then
        log:error('[bios]get boot certificates: boot option service is nil')
        return
    end
    return boot_options_ser:get_boot_certificates(ctx, self:get_system_id(obj.path))
end

function app_bios:ImportSecureBootCertificate(ctx, obj, db_type, cert_string, cert_type)
    local secure_boot_options_ser = bios_factory.get_service('secure_boot_options_service')
    if not secure_boot_options_ser then
        log:error('[bios]import secure boot certificate: secure boot option service is nil')
        return
    end
    return secure_boot_options_ser:import_secure_boot_certificate(ctx, db_type, cert_string,
        cert_type, self:get_system_id(obj.path))
end

function app_bios:ResetSecureBootCertificate(ctx, obj, db_type, reset_type)
    local secure_boot_options_ser = bios_factory.get_service('secure_boot_options_service')
    if not secure_boot_options_ser then
        log:error('[bios]reset secure boot certificate: secure boot option service is nil')
        return
    end
    return secure_boot_options_ser:reset_secure_boot_certificate(ctx, db_type, reset_type,
        self:get_system_id(obj.path))
end

function app_bios:GetSecureBootCertificate(ctx, obj)
    local secure_boot_options_ser = bios_factory.get_service('secure_boot_options_service')
    if not secure_boot_options_ser then
        log:error('[bios]get secure boot certificate: secure boot option service is nil')
        return
    end
    return secure_boot_options_ser:get_secure_boot_certificate(ctx, self:get_system_id(obj.path))
end

function app_bios:DataWipe(ctx, obj)
    return retirement.handle(ctx, self:get_system_id(obj.path))
end

function app_bios:GetDataWipeReport(obj, ctx)
    return retirement.get_report(obj, ctx)

end

return app_bios
