-- 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 open_db = require 'lsw.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 'lsw.orm_classes'
local ok, datas = pcall(require, 'lsw.datas')
if not ok then
    datas = nil -- 如果没有datas配置，证明当前组件不需要datas，仅打开数据库
end

local LanSwitchTypes = require 'lsw.json_types.LanSwitch'
local PropertiesTypes = require 'mdb.bmc.kepler.Object.PropertiesInterface'
local LanSwitchMockTypes = require 'lsw.json_types.LanSwitchMock'

local LanSwitch = mdb.register_object('/bmc/kepler/Chassis/:ChassisId/LanSwitchs/:Id', {
    {name = 'bmc.kepler.Chassis.LanSwitch', interface = LanSwitchTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

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

local LanSwitchMock = mdb.register_object('/bmc/kepler/Debug/LanSwitchMock', {
    {name = 'bmc.kepler.Debug.LanSwitchMock', interface = LanSwitchMockTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function LanSwitchMock:ctor()
    self.path = '/bmc/kepler/Debug/LanSwitchMock'
end

local model = require 'class.model'

local lsw_service = class(app_base.Service)

lsw_service.package = 'lsw'

function lsw_service:CreateLanSwitch(ChassisId, Id, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId .. '/LanSwitchs/' .. Id
    return object_manage.create_object('LanSwitch', path, path, prop_setting_cb)
end

function lsw_service:CreateLanSwitchMock(prop_setting_cb)
    return object_manage.create_object('LanSwitchMock', 'LanSwitchMock_0', '/bmc/kepler/Debug/LanSwitchMock',
        prop_setting_cb)
end

function lsw_service:ImplLanSwitchLanSwitchLswReset(cb)
    model.ImplLanSwitchLanSwitchLswReset(cb)
end

function lsw_service:ImplLanSwitchLanSwitchGetConfigInfo(cb)
    model.ImplLanSwitchLanSwitchGetConfigInfo(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockRegRead(cb)
    model.ImplLanSwitchMockLanSwitchMockRegRead(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockRegWrite(cb)
    model.ImplLanSwitchMockLanSwitchMockRegWrite(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockGetPortInfo(cb)
    model.ImplLanSwitchMockLanSwitchMockGetPortInfo(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockSetPortEnable(cb)
    model.ImplLanSwitchMockLanSwitchMockSetPortEnable(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockSetPortStpState(cb)
    model.ImplLanSwitchMockLanSwitchMockSetPortStpState(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockGetSwitchErrorCode(cb)
    model.ImplLanSwitchMockLanSwitchMockGetSwitchErrorCode(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockSetPortMacAddr(cb)
    model.ImplLanSwitchMockLanSwitchMockSetPortMacAddr(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockFlushPortAddr(cb)
    model.ImplLanSwitchMockLanSwitchMockFlushPortAddr(cb)
end

function lsw_service:ImplLanSwitchMockLanSwitchMockGetVlanInfo(cb)
    model.ImplLanSwitchMockLanSwitchMockGetVlanInfo(cb)
end

function lsw_service:get_bus()
    return self.bus
end

function lsw_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 lsw_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 lsw_service:ctor()
    self.ipmi_cmds = {}
    self.signal_slots = {}
    self.name = self.name or lsw_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)
    lsw_service.bus = self.bus
end

function lsw_service:pre_init()
    lsw_service.super.pre_init(self)
    self.persist = persist_client.new(self.bus, self.db, self, {})
    object_manage.set_persist_client(self.persist)
end

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

return lsw_service
