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

local PolicyTypes = require 'chassis.json_types.Policy'
local PropertiesTypes = require 'chassis.json_types.Properties'
local LedTypes = require 'chassis.json_types.Led'
local DimensionTypes = require 'chassis.json_types.Dimension'
local ChassisTypes = require 'chassis.json_types.Chassis'
local MetricTypes = require 'chassis.json_types.Metric'
local ManufactureTypes = require 'chassis.json_types.Manufacture'
local NCSICapabilitiesTypes = require 'chassis.json_types.NCSICapabilities'
local SuperPodLabelTypes = require 'chassis.json_types.SuperPodLabel'
local EnclosureTypes = require 'chassis.json_types.Enclosure'

local LedPolicy = mdb.register_object('/bmc/kepler/Systems/:SystemId/Leds', {
    {name = 'bmc.kepler.Systems.Led.Policy', interface = PolicyTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

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

local Led = mdb.register_object('/bmc/kepler/Systems/:SystemId/Leds/:ID', {
    {name = 'bmc.kepler.Systems.Led', interface = LedTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function Led:ctor(SystemId, ID)
    self.path = '/bmc/kepler/Systems/' .. SystemId .. '/Leds/' .. ID
end

local Dimension = mdb.register_object('/bmc/kepler/Chassis/:ChassisId/Dimension', {
    {name = 'bmc.kepler.Chassis.Dimension', interface = DimensionTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function Dimension:ctor(ChassisId)
    self.path = '/bmc/kepler/Chassis/' .. ChassisId .. '/Dimension'
end

local Chassis = mdb.register_object('/bmc/kepler/Chassis/:ChassisId', {
    {name = 'bmc.kepler.Chassis', interface = ChassisTypes.interface},
    {name = 'bmc.kepler.Metric', interface = MetricTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function Chassis:ctor(ChassisId)
    self.path = '/bmc/kepler/Chassis/' .. ChassisId
end

local DftChassisCover = mdb.register_object('/bmc/kepler/Manufacture/OperateTest/DftChassisCover/:Id', {
    {name = 'bmc.kepler.Manufacture', interface = ManufactureTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function DftChassisCover:ctor(Id)
    self.path = '/bmc/kepler/Manufacture/OperateTest/DftChassisCover/' .. Id
end

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

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

local DftPysicalLed = mdb.register_object('/bmc/kepler/Manufacture/CheckTest/DftPysicalLed/:Id', {
    {name = 'bmc.kepler.Manufacture', interface = ManufactureTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function DftPysicalLed:ctor(Id)
    self.path = '/bmc/kepler/Manufacture/CheckTest/DftPysicalLed/' .. Id
end

local DftUidButton = mdb.register_object('/bmc/kepler/Manufacture/OperateTest/DftUidButton/:Id', {
    {name = 'bmc.kepler.Manufacture', interface = ManufactureTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function DftUidButton:ctor(Id)
    self.path = '/bmc/kepler/Manufacture/OperateTest/DftUidButton/' .. Id
end

local DftLedIntelligence = mdb.register_object('/bmc/kepler/Manufacture/CheckTest/DftLedIntelligence/:Id', {
    {name = 'bmc.kepler.Manufacture', interface = ManufactureTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function DftLedIntelligence:ctor(Id)
    self.path = '/bmc/kepler/Manufacture/CheckTest/DftLedIntelligence/' .. Id
end

local DftLedTube = mdb.register_object('/bmc/kepler/Manufacture/CheckTest/DftLedTube/:Id', {
    {name = 'bmc.kepler.Manufacture', interface = ManufactureTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function DftLedTube:ctor(Id)
    self.path = '/bmc/kepler/Manufacture/CheckTest/DftLedTube/' .. Id
end

local DftLedTubeIntelligence = mdb.register_object('/bmc/kepler/Manufacture/CheckTest/DftLedTubeIntelligence/:Id', {
    {name = 'bmc.kepler.Manufacture', interface = ManufactureTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function DftLedTubeIntelligence:ctor(Id)
    self.path = '/bmc/kepler/Manufacture/CheckTest/DftLedTubeIntelligence/' .. Id
end

local SuperPodLabel = mdb.register_object('/bmc/kepler/Chassis/:ChassisId/SuperPodLabel', {
    {name = 'bmc.kepler.Chassis.SuperPodLabel', interface = SuperPodLabelTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function SuperPodLabel:ctor(ChassisId)
    self.path = '/bmc/kepler/Chassis/' .. ChassisId .. '/SuperPodLabel'
end

local DftButtonTest = mdb.register_object('/bmc/kepler/Manufacture/OperateTest/DftButtonTest/:Id', {
    {name = 'bmc.kepler.Manufacture', interface = ManufactureTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function DftButtonTest:ctor(Id)
    self.path = '/bmc/kepler/Manufacture/OperateTest/DftButtonTest/' .. Id
end

local Enclosure = mdb.register_object('/bmc/kepler/Chassis/:ChassisId/Enclosure', {
    {name = 'bmc.kepler.Chassis.Enclosure', interface = EnclosureTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function Enclosure:ctor(ChassisId)
    self.path = '/bmc/kepler/Chassis/' .. ChassisId .. '/Enclosure'
end

local model = require 'class.model'

local chassis_service = class(app_base.Service)

chassis_service.package = 'chassis'

function chassis_service:CreateLedPolicy(SystemId, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/Leds'
    return object_manage.create_object('LedPolicy', path, path, prop_setting_cb)
end

function chassis_service:CreateLed(SystemId, ID, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/Leds/' .. ID
    return object_manage.create_object('Led', path, path, prop_setting_cb)
end

function chassis_service:CreateDimension(ChassisId, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId .. '/Dimension'
    return object_manage.create_object('Dimension', path, path, prop_setting_cb)
end

function chassis_service:CreateChassis(ChassisId, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId
    return object_manage.create_object('Chassis', path, path, prop_setting_cb)
end

function chassis_service:CreateDftChassisCover(Id, prop_setting_cb)
    local path = '/bmc/kepler/Manufacture/OperateTest/DftChassisCover/' .. Id
    return object_manage.create_object('DftChassisCover', path, path, prop_setting_cb)
end

function chassis_service:CreateNCSICapabilities(SystemId, prop_setting_cb)
    local path = '/bmc/kepler/Systems/' .. SystemId .. '/NCSICapabilities'
    return object_manage.create_object('NCSICapabilities', path, path, prop_setting_cb)
end

function chassis_service:CreateDftPysicalLed(Id, prop_setting_cb)
    local path = '/bmc/kepler/Manufacture/CheckTest/DftPysicalLed/' .. Id
    return object_manage.create_object('DftPysicalLed', path, path, prop_setting_cb)
end

function chassis_service:CreateDftUidButton(Id, prop_setting_cb)
    local path = '/bmc/kepler/Manufacture/OperateTest/DftUidButton/' .. Id
    return object_manage.create_object('DftUidButton', path, path, prop_setting_cb)
end

function chassis_service:CreateDftLedIntelligence(Id, prop_setting_cb)
    local path = '/bmc/kepler/Manufacture/CheckTest/DftLedIntelligence/' .. Id
    return object_manage.create_object('DftLedIntelligence', path, path, prop_setting_cb)
end

function chassis_service:CreateDftLedTube(Id, prop_setting_cb)
    local path = '/bmc/kepler/Manufacture/CheckTest/DftLedTube/' .. Id
    return object_manage.create_object('DftLedTube', path, path, prop_setting_cb)
end

function chassis_service:CreateDftLedTubeIntelligence(Id, prop_setting_cb)
    local path = '/bmc/kepler/Manufacture/CheckTest/DftLedTubeIntelligence/' .. Id
    return object_manage.create_object('DftLedTubeIntelligence', path, path, prop_setting_cb)
end

function chassis_service:CreateSuperPodLabel(ChassisId, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId .. '/SuperPodLabel'
    return object_manage.create_object('SuperPodLabel', path, path, prop_setting_cb)
end

function chassis_service:CreateDftButtonTest(Id, prop_setting_cb)
    local path = '/bmc/kepler/Manufacture/OperateTest/DftButtonTest/' .. Id
    return object_manage.create_object('DftButtonTest', path, path, prop_setting_cb)
end

function chassis_service:CreateEnclosure(ChassisId, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId .. '/Enclosure'
    return object_manage.create_object('Enclosure', path, path, prop_setting_cb)
end

function chassis_service:ImplLedLedSetState(cb)
    model.ImplLedLedSetState(cb)
end

function chassis_service:ImplChassisMetricGetData(cb)
    model.ImplChassisMetricGetData(cb)
end

function chassis_service:ImplChassisMetricGetItems(cb)
    model.ImplChassisMetricGetItems(cb)
end

function chassis_service:ImplChassisMetricSynDataAcquisitionEnable(cb)
    model.ImplChassisMetricSynDataAcquisitionEnable(cb)
end

function chassis_service:ImplDftChassisCoverManufactureStart(cb)
    model.ImplDftChassisCoverManufactureStart(cb)
end

function chassis_service:ImplDftChassisCoverManufactureStop(cb)
    model.ImplDftChassisCoverManufactureStop(cb)
end

function chassis_service:ImplDftChassisCoverManufactureGetResult(cb)
    model.ImplDftChassisCoverManufactureGetResult(cb)
end

function chassis_service:ImplDftPysicalLedManufactureStart(cb)
    model.ImplDftPysicalLedManufactureStart(cb)
end

function chassis_service:ImplDftPysicalLedManufactureStop(cb)
    model.ImplDftPysicalLedManufactureStop(cb)
end

function chassis_service:ImplDftPysicalLedManufactureGetResult(cb)
    model.ImplDftPysicalLedManufactureGetResult(cb)
end

function chassis_service:ImplDftUidButtonManufactureStart(cb)
    model.ImplDftUidButtonManufactureStart(cb)
end

function chassis_service:ImplDftUidButtonManufactureStop(cb)
    model.ImplDftUidButtonManufactureStop(cb)
end

function chassis_service:ImplDftUidButtonManufactureGetResult(cb)
    model.ImplDftUidButtonManufactureGetResult(cb)
end

function chassis_service:ImplDftLedIntelligenceManufactureStart(cb)
    model.ImplDftLedIntelligenceManufactureStart(cb)
end

function chassis_service:ImplDftLedIntelligenceManufactureStop(cb)
    model.ImplDftLedIntelligenceManufactureStop(cb)
end

function chassis_service:ImplDftLedIntelligenceManufactureGetResult(cb)
    model.ImplDftLedIntelligenceManufactureGetResult(cb)
end

function chassis_service:ImplDftLedTubeManufactureStart(cb)
    model.ImplDftLedTubeManufactureStart(cb)
end

function chassis_service:ImplDftLedTubeManufactureStop(cb)
    model.ImplDftLedTubeManufactureStop(cb)
end

function chassis_service:ImplDftLedTubeManufactureGetResult(cb)
    model.ImplDftLedTubeManufactureGetResult(cb)
end

function chassis_service:ImplDftLedTubeIntelligenceManufactureStart(cb)
    model.ImplDftLedTubeIntelligenceManufactureStart(cb)
end

function chassis_service:ImplDftLedTubeIntelligenceManufactureStop(cb)
    model.ImplDftLedTubeIntelligenceManufactureStop(cb)
end

function chassis_service:ImplDftLedTubeIntelligenceManufactureGetResult(cb)
    model.ImplDftLedTubeIntelligenceManufactureGetResult(cb)
end

function chassis_service:ImplSuperPodLabelSuperPodLabelSetSuperPodId(cb)
    model.ImplSuperPodLabelSuperPodLabelSetSuperPodId(cb)
end

function chassis_service:ImplSuperPodLabelSuperPodLabelSetServerIndex(cb)
    model.ImplSuperPodLabelSuperPodLabelSetServerIndex(cb)
end

function chassis_service:ImplSuperPodLabelSuperPodLabelSetSuperPodSize(cb)
    model.ImplSuperPodLabelSuperPodLabelSetSuperPodSize(cb)
end

function chassis_service:ImplSuperPodLabelSuperPodLabelRestoreDefaults(cb)
    model.ImplSuperPodLabelSuperPodLabelRestoreDefaults(cb)
end

function chassis_service:ImplDftButtonTestManufactureStart(cb)
    model.ImplDftButtonTestManufactureStart(cb)
end

function chassis_service:ImplDftButtonTestManufactureStop(cb)
    model.ImplDftButtonTestManufactureStop(cb)
end

function chassis_service:ImplDftButtonTestManufactureGetResult(cb)
    model.ImplDftButtonTestManufactureGetResult(cb)
end

---@param mdb_object object
---@param MetricName string
---@param TagPath string
function chassis_service:ChassisMetricCollectSignal(mdb_object, MetricName, TagPath)
    self.bus:signal(mdb_object.path, 'bmc.kepler.Metric', 'CollectSignal', 'a{ss}ss', context.get_context() or {},
        MetricName, TagPath)
end

function chassis_service:get_bus()
    return self.bus
end

function chassis_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 chassis_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 chassis_service:ctor()
    self.ipmi_cmds = {}
    self.signal_slots = {}
    self.name = self.name or chassis_service.package
    self.db = open_db(':memory:', datas)

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

function chassis_service:pre_init()
    chassis_service.super.pre_init(self)
    self.persist = persist_client.new(self.bus, self.db, self, {
        ['t_LedPolicy'] = true,
        ['t_Led'] = true,
        ['t_Chassis'] = true,
        ['t_SuperPodLabel'] = true
    })
    object_manage.set_persist_client(self.persist)
end

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

return chassis_service
