-- 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 validate = require 'mc.validate'
local utils = require 'mc.utils'
local mdb = require 'mc.mdb'

local PCIeSlot = {}

---@class PCIeSlot.ReadyToEnumerate
---@field ReadyToEnumerate boolean
local TReadyToEnumerate = {}
TReadyToEnumerate.__index = TReadyToEnumerate
TReadyToEnumerate.group = {}

local function TReadyToEnumerate_from_obj(obj)
    return setmetatable(obj, TReadyToEnumerate)
end

function TReadyToEnumerate.new(ReadyToEnumerate)
    return TReadyToEnumerate_from_obj({ReadyToEnumerate = ReadyToEnumerate})
end
---@param obj PCIeSlot.ReadyToEnumerate
function TReadyToEnumerate:init_from_obj(obj)
    self.ReadyToEnumerate = obj.ReadyToEnumerate
end

function TReadyToEnumerate:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TReadyToEnumerate.group)
end

TReadyToEnumerate.from_obj = TReadyToEnumerate_from_obj

TReadyToEnumerate.proto_property = {'ReadyToEnumerate'}

TReadyToEnumerate.default = {false}

TReadyToEnumerate.struct = {{name = 'ReadyToEnumerate', is_array = false, struct = nil}}

function TReadyToEnumerate:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'ReadyToEnumerate', self.ReadyToEnumerate, 'bool', true, errs, need_convert)

    TReadyToEnumerate:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TReadyToEnumerate.proto_property, errs, need_convert)
    return self
end

function TReadyToEnumerate:unpack(_)
    return self.ReadyToEnumerate
end

PCIeSlot.ReadyToEnumerate = TReadyToEnumerate

---@class PCIeSlot.PowerState
---@field PowerState string
local TPowerState = {}
TPowerState.__index = TPowerState
TPowerState.group = {}

local function TPowerState_from_obj(obj)
    return setmetatable(obj, TPowerState)
end

function TPowerState.new(PowerState)
    return TPowerState_from_obj({PowerState = PowerState or [=[Off]=]})
end
---@param obj PCIeSlot.PowerState
function TPowerState:init_from_obj(obj)
    self.PowerState = obj.PowerState or [=[Off]=]
end

function TPowerState:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TPowerState.group)
end

TPowerState.from_obj = TPowerState_from_obj

TPowerState.proto_property = {'PowerState'}

TPowerState.default = {''}

TPowerState.struct = {{name = 'PowerState', is_array = false, struct = nil}}

function TPowerState:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'PowerState', self.PowerState, 'string', true, errs, need_convert)

    if self.PowerState ~= nil then
        validate.Enum(prefix .. 'PowerState', self.PowerState, '', {'Off', 'On'}, errs, need_convert)
    end

    TPowerState:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TPowerState.proto_property, errs, need_convert)
    return self
end

function TPowerState:unpack(_)
    return self.PowerState
end

PCIeSlot.PowerState = TPowerState

---@class PCIeSlot.SupportedComponentTypes
---@field SupportedComponentTypes integer[]
local TSupportedComponentTypes = {}
TSupportedComponentTypes.__index = TSupportedComponentTypes
TSupportedComponentTypes.group = {}

local function TSupportedComponentTypes_from_obj(obj)
    return setmetatable(obj, TSupportedComponentTypes)
end

function TSupportedComponentTypes.new(SupportedComponentTypes)
    return TSupportedComponentTypes_from_obj({SupportedComponentTypes = SupportedComponentTypes})
end
---@param obj PCIeSlot.SupportedComponentTypes
function TSupportedComponentTypes:init_from_obj(obj)
    self.SupportedComponentTypes = obj.SupportedComponentTypes
end

function TSupportedComponentTypes:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSupportedComponentTypes.group)
end

TSupportedComponentTypes.from_obj = TSupportedComponentTypes_from_obj

TSupportedComponentTypes.proto_property = {'SupportedComponentTypes'}

TSupportedComponentTypes.default = {{}}

TSupportedComponentTypes.struct = {{name = 'SupportedComponentTypes', is_array = true, struct = nil}}

function TSupportedComponentTypes:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.OptionalArray(prefix .. 'SupportedComponentTypes', self.SupportedComponentTypes, 'uint8', true, errs,
        need_convert)

    TSupportedComponentTypes:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSupportedComponentTypes.proto_property, errs, need_convert)
    return self
end

function TSupportedComponentTypes:unpack(_)
    return self.SupportedComponentTypes
end

PCIeSlot.SupportedComponentTypes = TSupportedComponentTypes

---@class PCIeSlot.SlotId
---@field SlotId integer
local TSlotId = {}
TSlotId.__index = TSlotId
TSlotId.group = {}

local function TSlotId_from_obj(obj)
    return setmetatable(obj, TSlotId)
end

function TSlotId.new(SlotId)
    return TSlotId_from_obj({SlotId = SlotId})
end
---@param obj PCIeSlot.SlotId
function TSlotId:init_from_obj(obj)
    self.SlotId = obj.SlotId
end

function TSlotId:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSlotId.group)
end

TSlotId.from_obj = TSlotId_from_obj

TSlotId.proto_property = {'SlotId'}

TSlotId.default = {0}

TSlotId.struct = {{name = 'SlotId', is_array = false, struct = nil}}

function TSlotId:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'SlotId', self.SlotId, 'uint8', true, errs, need_convert)

    TSlotId:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSlotId.proto_property, errs, need_convert)
    return self
end

function TSlotId:unpack(_)
    return self.SlotId
end

PCIeSlot.SlotId = TSlotId

---@class PCIeSlot.PowerControlRsp
local TPowerControlRsp = {}
TPowerControlRsp.__index = TPowerControlRsp
TPowerControlRsp.group = {}

local function TPowerControlRsp_from_obj(obj)
    return setmetatable(obj, TPowerControlRsp)
end

function TPowerControlRsp.new()
    return TPowerControlRsp_from_obj({})
end
---@param obj PCIeSlot.PowerControlRsp
function TPowerControlRsp:init_from_obj(obj)

end

function TPowerControlRsp:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TPowerControlRsp.group)
end

TPowerControlRsp.from_obj = TPowerControlRsp_from_obj

TPowerControlRsp.proto_property = {}

TPowerControlRsp.default = {}

TPowerControlRsp.struct = {}

function TPowerControlRsp:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    TPowerControlRsp:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TPowerControlRsp.proto_property, errs, need_convert)
    return self
end

function TPowerControlRsp:unpack(_)
end

PCIeSlot.PowerControlRsp = TPowerControlRsp

---@class PCIeSlot.PowerControlReq
---@field PowerState string
local TPowerControlReq = {}
TPowerControlReq.__index = TPowerControlReq
TPowerControlReq.group = {}

local function TPowerControlReq_from_obj(obj)
    return setmetatable(obj, TPowerControlReq)
end

function TPowerControlReq.new(PowerState)
    return TPowerControlReq_from_obj({PowerState = PowerState})
end
---@param obj PCIeSlot.PowerControlReq
function TPowerControlReq:init_from_obj(obj)
    self.PowerState = obj.PowerState
end

function TPowerControlReq:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TPowerControlReq.group)
end

TPowerControlReq.from_obj = TPowerControlReq_from_obj

TPowerControlReq.proto_property = {'PowerState'}

TPowerControlReq.default = {''}

TPowerControlReq.struct = {{name = 'PowerState', is_array = false, struct = nil}}

function TPowerControlReq:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'PowerState', self.PowerState, 'string', false, errs, need_convert)

    TPowerControlReq:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TPowerControlReq.proto_property, errs, need_convert)
    return self
end

function TPowerControlReq:unpack(_)
    return self.PowerState
end

PCIeSlot.PowerControlReq = TPowerControlReq

PCIeSlot.interface = mdb.register_interface('bmc.kepler.Systems.PCIeSlot', {
    SlotId = {'y', {}, true, nil},
    SupportedComponentTypes = {'ay', {}, true, nil},
    PowerState = {'s', {'EMIT_CHANGE'}, true, 'Off'},
    ReadyToEnumerate = {'b', nil, true, nil}
}, {PowerControl = {'a{ss}s', '', TPowerControlReq, TPowerControlRsp}}, {})

return PCIeSlot
