-- Copyright (c) 2025 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 ipmi = require 'ipmi'
local mdb = require 'mc.mdb'
local skynet = require 'skynet'
local class = require 'mc.class'
local open_db = require 'bios.db'
local app_base = require 'mc.service_app_base'
local open_local_db = require 'bios.local_db'
local object_manage = require 'mc.mdb.object_manage'
local persist_client = require 'persistence.persist_client_lib'
local orm_classes = require 'bios.orm_classes'
local ok, datas = pcall(require, 'bios.datas')
if not ok then
    datas = nil -- 如果没有datas配置，证明当前组件不需要datas，仅打开数据库
end

local BiosTypes = require 'bios.json_types.Bios'
local RetirementTypes = require 'bios.json_types.Retirement'
local PropertiesTypes = require 'mdb.bmc.kepler.Object.PropertiesInterface'
local SmBiosTypes = require 'bios.json_types.SmBios'
local BootOptionsTypes = require 'bios.json_types.BootOptions'
local SecureBootOptionsTypes = require 'bios.json_types.SecureBootOptions'
local BiosUpgradeServiceTypes = require 'bios.json_types.BiosUpgradeService'
local SystemFirmwareProgressStatusTypes = require 'bios.json_types.SystemFirmwareProgressStatus'
local IPMIEventTypes = require 'bios.json_types.IPMIEvent'

local Bios = mdb.register_object('/bmc/kepler/Systems/:SystemId/Bios', {
    {name = 'bmc.kepler.Systems.Bios', interface = BiosTypes.interface},
    {name = 'bmc.kepler.LifeCycle.Retirement', interface = RetirementTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function Bios:ctor(SystemId)
    self.path = '/bmc/kepler/Systems/' .. SystemId .. '/Bios'
end

local SmBios = mdb.register_object('/bmc/kepler/Systems/:SystemId/SmBios', {
    {name = 'bmc.kepler.Systems.SmBios', interface = SmBiosTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function SmBios:ctor(SystemId)
    self.path = '/bmc/kepler/Systems/' .. SystemId .. '/SmBios'
end

local BootOptions = mdb.register_object('/bmc/kepler/Systems/:Id/BootOptions', {
    {name = 'bmc.kepler.Systems.BootOptions', interface = BootOptionsTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function BootOptions:ctor(Id)
    self.path = '/bmc/kepler/Systems/' .. Id .. '/BootOptions'
end

local SecureBootOptions = mdb.register_object('/bmc/kepler/Systems/:SystemId/SecureBootOptions', {
    {name = 'bmc.kepler.Systems.SecureBootOptions', interface = SecureBootOptionsTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function SecureBootOptions:ctor(SystemId)
    self.path = '/bmc/kepler/Systems/' .. SystemId .. '/SecureBootOptions'
end

local BiosUpgradeService = mdb.register_object('/bmc/kepler/Systems/:SystemId/BiosUpgradeService', {
    {name = 'bmc.kepler.Systems.BiosUpgradeService', interface = BiosUpgradeServiceTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function BiosUpgradeService:ctor(SystemId)
    self.path = '/bmc/kepler/Systems/' .. SystemId .. '/BiosUpgradeService'
end

local SystemFirmwareProgress = mdb.register_object('/bmc/kepler/Systems/:SystemId/SystemFirmwareProgress', {
    {name = 'bmc.kepler.Systems.SystemFirmwareProgress.Status', interface = SystemFirmwareProgressStatusTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function SystemFirmwareProgress:ctor(SystemId)
    self.path = '/bmc/kepler/Systems/' .. SystemId .. '/SystemFirmwareProgress'
end

local BaseOSBoot = mdb.register_object('/bmc/kepler/Systems/:SystemId/EventEntries/BaseOSBoot', {
    {name = 'bmc.kepler.Systems.IPMIEvent', interface = IPMIEventTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function BaseOSBoot:ctor(SystemId)
    self.path = '/bmc/kepler/Systems/' .. SystemId .. '/EventEntries/BaseOSBoot'
end

local model = require 'class.model'

local bios_service = class(app_base.Service)

bios_service.package = 'bios'

function bios_service:CreateBios(SystemId, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/Bios'
    return object_manage.create_object('Bios', path, path, prop_setting_cb)
end

function bios_service:CreateSmBios(SystemId, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/SmBios'
    return object_manage.create_object('SmBios', path, path, prop_setting_cb)
end

function bios_service:CreateBootOptions(Id, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. Id .. '/BootOptions'
    return object_manage.create_object('BootOptions', path, path, prop_setting_cb)
end

function bios_service:CreateSecureBootOptions(SystemId, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/SecureBootOptions'
    return object_manage.create_object('SecureBootOptions', path, path, prop_setting_cb)
end

function bios_service:CreateBiosUpgradeService(SystemId, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/BiosUpgradeService'
    return object_manage.create_object('BiosUpgradeService', path, path, prop_setting_cb)
end

function bios_service:CreateSystemFirmwareProgress(SystemId, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/SystemFirmwareProgress'
    return object_manage.create_object('SystemFirmwareProgress', path, path, prop_setting_cb)
end

function bios_service:CreateBaseOSBoot(SystemId, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/EventEntries/BaseOSBoot'
    return object_manage.create_object('BaseOSBoot', path, path, prop_setting_cb)
end

function bios_service:ImplBiosBiosClearCmos(cb)
    model.ImplBiosBiosClearCmos(cb)
end

function bios_service:ImplBiosBiosResetSetupConfig(cb)
    model.ImplBiosBiosResetSetupConfig(cb)
end

function bios_service:ImplBiosBiosChangePassword(cb)
    model.ImplBiosBiosChangePassword(cb)
end

function bios_service:ImplBiosBiosImportBiosSetup(cb)
    model.ImplBiosBiosImportBiosSetup(cb)
end

function bios_service:ImplBiosBiosGetCurrentValueSetting(cb)
    model.ImplBiosBiosGetCurrentValueSetting(cb)
end

function bios_service:ImplBiosBiosRemoveCachedSettings(cb)
    model.ImplBiosBiosRemoveCachedSettings(cb)
end

function bios_service:ImplBiosBiosExportFirmware(cb)
    model.ImplBiosBiosExportFirmware(cb)
end

function bios_service:ImplBiosBiosSetBiosConfigActiveMode(cb)
    model.ImplBiosBiosSetBiosConfigActiveMode(cb)
end

function bios_service:ImplBiosBiosSetBiosLogEnabled(cb)
    model.ImplBiosBiosSetBiosLogEnabled(cb)
end

function bios_service:ImplBiosBiosExportBiosSetup(cb)
    model.ImplBiosBiosExportBiosSetup(cb)
end

function bios_service:ImplBiosRetirementDataWipe(cb)
    model.ImplBiosRetirementDataWipe(cb)
end

function bios_service:ImplBiosRetirementGetReport(cb)
    model.ImplBiosRetirementGetReport(cb)
end

function bios_service:ImplBootOptionsBootOptionsShieldIpmiModifyBootModeSupport(cb)
    model.ImplBootOptionsBootOptionsShieldIpmiModifyBootModeSupport(cb)
end

function bios_service:ImplBootOptionsBootOptionsImportCertificate(cb)
    model.ImplBootOptionsBootOptionsImportCertificate(cb)
end

function bios_service:ImplBootOptionsBootOptionsImportCrl(cb)
    model.ImplBootOptionsBootOptionsImportCrl(cb)
end

function bios_service:ImplBootOptionsBootOptionsResetCrl(cb)
    model.ImplBootOptionsBootOptionsResetCrl(cb)
end

function bios_service:ImplBootOptionsBootOptionsResetCertificate(cb)
    model.ImplBootOptionsBootOptionsResetCertificate(cb)
end

function bios_service:ImplBootOptionsBootOptionsSetBootOrder(cb)
    model.ImplBootOptionsBootOptionsSetBootOrder(cb)
end

function bios_service:ImplBootOptionsBootOptionsSetStartOption(cb)
    model.ImplBootOptionsBootOptionsSetStartOption(cb)
end

function bios_service:ImplBootOptionsBootOptionsSetStartOptionFlag(cb)
    model.ImplBootOptionsBootOptionsSetStartOptionFlag(cb)
end

function bios_service:ImplBootOptionsBootOptionsSetBootMode(cb)
    model.ImplBootOptionsBootOptionsSetBootMode(cb)
end

function bios_service:ImplBootOptionsBootOptionsGetCertificate(cb)
    model.ImplBootOptionsBootOptionsGetCertificate(cb)
end

function bios_service:ImplSecureBootOptionsSecureBootOptionsImportCertificate(cb)
    model.ImplSecureBootOptionsSecureBootOptionsImportCertificate(cb)
end

function bios_service:ImplSecureBootOptionsSecureBootOptionsResetCertificate(cb)
    model.ImplSecureBootOptionsSecureBootOptionsResetCertificate(cb)
end

function bios_service:ImplSecureBootOptionsSecureBootOptionsGetCertificate(cb)
    model.ImplSecureBootOptionsSecureBootOptionsGetCertificate(cb)
end

function bios_service:ImplBiosUpgradeServiceBiosUpgradeServiceActivateFirmware(cb)
    model.ImplBiosUpgradeServiceBiosUpgradeServiceActivateFirmware(cb)
end

function bios_service:ImplBiosUpgradeServiceBiosUpgradeServiceExportBiosFirmware(cb)
    model.ImplBiosUpgradeServiceBiosUpgradeServiceExportBiosFirmware(cb)
end

function bios_service:ImplBiosUpgradeServiceBiosUpgradeServiceGetFirmwareInfo(cb)
    model.ImplBiosUpgradeServiceBiosUpgradeServiceGetFirmwareInfo(cb)
end

function bios_service:get_bus()
    return self.bus
end

function bios_service:register_ipmi_cmd(ipmi_cmd, cb)
    self.ipmi_cmds[ipmi_cmd.name] = ipmi.register_ipmi_cmd(self.bus, self.service_name, ipmi_cmd,
        cb or self[ipmi_cmd.name])
end

function bios_service:unregister_ipmi_cmd(ipmi_cmd)
    local cmd_obj = self.ipmi_cmds[ipmi_cmd.name]
    if not cmd_obj then
        return
    end

    cmd_obj:unregister()
    self.ipmi_cmds[ipmi_cmd.name] = nil
end

function bios_service:ctor()
    self.ipmi_cmds = {}
    self.signal_slots = {}
    self.name = self.name or bios_service.package
    self.db = open_db(':memory:', datas)
    self.local_db = open_local_db(app_base.Service:get_local_db_path(self.name) .. '/bios.db', datas, 'poweroff')
    if skynet.getenv('TEST_DATA_DIR') then
        self.reset_local_db = open_local_db(skynet.getenv('TEST_DATA_DIR') .. '/bios_reset.db', datas, 'reset')
    else
        self.reset_local_db = open_local_db('/opt/bmc/pram/persistence.local/bios.db', datas, 'reset')
    end

    orm_classes.init(self.db)
    self.bus:request_name(app_base.Service.get_service_name(self.name))
    model.init(self.bus)
    bios_service.bus = self.bus
end

function bios_service:pre_init()
    bios_service.super.pre_init(self)
    self.persist = persist_client.new(self.bus, self.db, self, {['t_base_os_boot'] = true, ['t_krun_info'] = true})
    object_manage.set_persist_client(self.persist)
end

function bios_service:init()
    bios_service.super.init(self)
end

return bios_service
