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

local PcieAddrInfo = {}

---@class PcieAddrInfo.SlotType
---@field SlotType string
local TSlotType = {}
TSlotType.__index = TSlotType
TSlotType.group = {}

local function TSlotType_from_obj(obj)
    return setmetatable(obj, TSlotType)
end

function TSlotType.new(SlotType)
    return TSlotType_from_obj({SlotType = SlotType})
end
---@param obj PcieAddrInfo.SlotType
function TSlotType:init_from_obj(obj)
    self.SlotType = obj.SlotType
end

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

TSlotType.from_obj = TSlotType_from_obj

TSlotType.proto_property = {'SlotType'}

TSlotType.default = {''}

TSlotType.struct = {{name = 'SlotType', is_array = false, struct = nil}}

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

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

    if self.SlotType ~= nil then
        validate.Enum(prefix .. 'SlotType', self.SlotType, '',
            {'FullLength', 'HalfLength', 'LowProfile', 'M2', 'Mini', 'OCP3Large', 'OCP3Small', 'OEM', 'U2'}, errs,
            need_convert)
    end

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

function TSlotType:unpack(_)
    return self.SlotType
end

PcieAddrInfo.SlotType = TSlotType

---@class PcieAddrInfo.PCIeType
---@field PCIeType string
local TPCIeType = {}
TPCIeType.__index = TPCIeType
TPCIeType.group = {}

local function TPCIeType_from_obj(obj)
    return setmetatable(obj, TPCIeType)
end

function TPCIeType.new(PCIeType)
    return TPCIeType_from_obj({PCIeType = PCIeType})
end
---@param obj PcieAddrInfo.PCIeType
function TPCIeType:init_from_obj(obj)
    self.PCIeType = obj.PCIeType
end

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

TPCIeType.from_obj = TPCIeType_from_obj

TPCIeType.proto_property = {'PCIeType'}

TPCIeType.default = {''}

TPCIeType.struct = {{name = 'PCIeType', is_array = false, struct = nil}}

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

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

    if self.PCIeType ~= nil then
        validate.Enum(prefix .. 'PCIeType', self.PCIeType, '', {'Gen1', 'Gen2', 'Gen3', 'Gen4', 'Gen5', 'Gen6'}, errs,
            need_convert)
    end

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

function TPCIeType:unpack(_)
    return self.PCIeType
end

PcieAddrInfo.PCIeType = TPCIeType

---@class PcieAddrInfo.Lanes
---@field Lanes integer
local TLanes = {}
TLanes.__index = TLanes
TLanes.group = {}

local function TLanes_from_obj(obj)
    return setmetatable(obj, TLanes)
end

function TLanes.new(Lanes)
    return TLanes_from_obj({Lanes = Lanes})
end
---@param obj PcieAddrInfo.Lanes
function TLanes:init_from_obj(obj)
    self.Lanes = obj.Lanes
end

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

TLanes.from_obj = TLanes_from_obj

TLanes.proto_property = {'Lanes'}

TLanes.default = {0}

TLanes.struct = {{name = 'Lanes', is_array = false, struct = nil}}

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

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

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

function TLanes:unpack(_)
    return self.Lanes
end

PcieAddrInfo.Lanes = TLanes

---@class PcieAddrInfo.PortID
---@field PortID integer
local TPortID = {}
TPortID.__index = TPortID
TPortID.group = {}

local function TPortID_from_obj(obj)
    return setmetatable(obj, TPortID)
end

function TPortID.new(PortID)
    return TPortID_from_obj({PortID = PortID or 255})
end
---@param obj PcieAddrInfo.PortID
function TPortID:init_from_obj(obj)
    self.PortID = obj.PortID or 255
end

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

TPortID.from_obj = TPortID_from_obj

TPortID.proto_property = {'PortID'}

TPortID.default = {0}

TPortID.struct = {{name = 'PortID', is_array = false, struct = nil}}

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

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

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

function TPortID:unpack(_)
    return self.PortID
end

PcieAddrInfo.PortID = TPortID

---@class PcieAddrInfo.DeviceID
---@field DeviceID integer
local TDeviceID = {}
TDeviceID.__index = TDeviceID
TDeviceID.group = {}

local function TDeviceID_from_obj(obj)
    return setmetatable(obj, TDeviceID)
end

function TDeviceID.new(DeviceID)
    return TDeviceID_from_obj({DeviceID = DeviceID})
end
---@param obj PcieAddrInfo.DeviceID
function TDeviceID:init_from_obj(obj)
    self.DeviceID = obj.DeviceID
end

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

TDeviceID.from_obj = TDeviceID_from_obj

TDeviceID.proto_property = {'DeviceID'}

TDeviceID.default = {0}

TDeviceID.struct = {{name = 'DeviceID', is_array = false, struct = nil}}

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

    validate.Optional(prefix .. 'DeviceID', self.DeviceID, 'uint16', true, errs, need_convert)

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

function TDeviceID:unpack(_)
    return self.DeviceID
end

PcieAddrInfo.DeviceID = TDeviceID

---@class PcieAddrInfo.VendorID
---@field VendorID integer
local TVendorID = {}
TVendorID.__index = TVendorID
TVendorID.group = {}

local function TVendorID_from_obj(obj)
    return setmetatable(obj, TVendorID)
end

function TVendorID.new(VendorID)
    return TVendorID_from_obj({VendorID = VendorID})
end
---@param obj PcieAddrInfo.VendorID
function TVendorID:init_from_obj(obj)
    self.VendorID = obj.VendorID
end

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

TVendorID.from_obj = TVendorID_from_obj

TVendorID.proto_property = {'VendorID'}

TVendorID.default = {0}

TVendorID.struct = {{name = 'VendorID', is_array = false, struct = nil}}

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

    validate.Optional(prefix .. 'VendorID', self.VendorID, 'uint16', true, errs, need_convert)

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

function TVendorID:unpack(_)
    return self.VendorID
end

PcieAddrInfo.VendorID = TVendorID

---@class PcieAddrInfo.Function
---@field Function integer
local TFunction = {}
TFunction.__index = TFunction
TFunction.group = {}

local function TFunction_from_obj(obj)
    return setmetatable(obj, TFunction)
end

function TFunction.new(Function)
    return TFunction_from_obj({Function = Function})
end
---@param obj PcieAddrInfo.Function
function TFunction:init_from_obj(obj)
    self.Function = obj.Function
end

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

TFunction.from_obj = TFunction_from_obj

TFunction.proto_property = {'Function'}

TFunction.default = {0}

TFunction.struct = {{name = 'Function', is_array = false, struct = nil}}

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

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

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

function TFunction:unpack(_)
    return self.Function
end

PcieAddrInfo.Function = TFunction

---@class PcieAddrInfo.Device
---@field Device integer
local TDevice = {}
TDevice.__index = TDevice
TDevice.group = {}

local function TDevice_from_obj(obj)
    return setmetatable(obj, TDevice)
end

function TDevice.new(Device)
    return TDevice_from_obj({Device = Device})
end
---@param obj PcieAddrInfo.Device
function TDevice:init_from_obj(obj)
    self.Device = obj.Device
end

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

TDevice.from_obj = TDevice_from_obj

TDevice.proto_property = {'Device'}

TDevice.default = {0}

TDevice.struct = {{name = 'Device', is_array = false, struct = nil}}

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

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

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

function TDevice:unpack(_)
    return self.Device
end

PcieAddrInfo.Device = TDevice

---@class PcieAddrInfo.Bus
---@field Bus integer
local TBus = {}
TBus.__index = TBus
TBus.group = {}

local function TBus_from_obj(obj)
    return setmetatable(obj, TBus)
end

function TBus.new(Bus)
    return TBus_from_obj({Bus = Bus})
end
---@param obj PcieAddrInfo.Bus
function TBus:init_from_obj(obj)
    self.Bus = obj.Bus
end

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

TBus.from_obj = TBus_from_obj

TBus.proto_property = {'Bus'}

TBus.default = {0}

TBus.struct = {{name = 'Bus', is_array = false, struct = nil}}

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

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

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

function TBus:unpack(_)
    return self.Bus
end

PcieAddrInfo.Bus = TBus

---@class PcieAddrInfo.Segment
---@field Segment integer
local TSegment = {}
TSegment.__index = TSegment
TSegment.group = {}

local function TSegment_from_obj(obj)
    return setmetatable(obj, TSegment)
end

function TSegment.new(Segment)
    return TSegment_from_obj({Segment = Segment})
end
---@param obj PcieAddrInfo.Segment
function TSegment:init_from_obj(obj)
    self.Segment = obj.Segment
end

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

TSegment.from_obj = TSegment_from_obj

TSegment.proto_property = {'Segment'}

TSegment.default = {0}

TSegment.struct = {{name = 'Segment', is_array = false, struct = nil}}

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

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

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

function TSegment:unpack(_)
    return self.Segment
end

PcieAddrInfo.Segment = TSegment

---@class PcieAddrInfo.SocketID
---@field SocketID integer
local TSocketID = {}
TSocketID.__index = TSocketID
TSocketID.group = {}

local function TSocketID_from_obj(obj)
    return setmetatable(obj, TSocketID)
end

function TSocketID.new(SocketID)
    return TSocketID_from_obj({SocketID = SocketID})
end
---@param obj PcieAddrInfo.SocketID
function TSocketID:init_from_obj(obj)
    self.SocketID = obj.SocketID
end

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

TSocketID.from_obj = TSocketID_from_obj

TSocketID.proto_property = {'SocketID'}

TSocketID.default = {0}

TSocketID.struct = {{name = 'SocketID', is_array = false, struct = nil}}

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

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

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

function TSocketID:unpack(_)
    return self.SocketID
end

PcieAddrInfo.SocketID = TSocketID

---@class PcieAddrInfo.ControllerType
---@field ControllerType integer
local TControllerType = {}
TControllerType.__index = TControllerType
TControllerType.group = {}

local function TControllerType_from_obj(obj)
    return setmetatable(obj, TControllerType)
end

function TControllerType.new(ControllerType)
    return TControllerType_from_obj({ControllerType = ControllerType})
end
---@param obj PcieAddrInfo.ControllerType
function TControllerType:init_from_obj(obj)
    self.ControllerType = obj.ControllerType
end

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

TControllerType.from_obj = TControllerType_from_obj

TControllerType.proto_property = {'ControllerType'}

TControllerType.default = {0}

TControllerType.struct = {{name = 'ControllerType', is_array = false, struct = nil}}

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

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

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

function TControllerType:unpack(_)
    return self.ControllerType
end

PcieAddrInfo.ControllerType = TControllerType

---@class PcieAddrInfo.ControllerIndex
---@field ControllerIndex integer
local TControllerIndex = {}
TControllerIndex.__index = TControllerIndex
TControllerIndex.group = {}

local function TControllerIndex_from_obj(obj)
    return setmetatable(obj, TControllerIndex)
end

function TControllerIndex.new(ControllerIndex)
    return TControllerIndex_from_obj({ControllerIndex = ControllerIndex})
end
---@param obj PcieAddrInfo.ControllerIndex
function TControllerIndex:init_from_obj(obj)
    self.ControllerIndex = obj.ControllerIndex
end

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

TControllerIndex.from_obj = TControllerIndex_from_obj

TControllerIndex.proto_property = {'ControllerIndex'}

TControllerIndex.default = {0}

TControllerIndex.struct = {{name = 'ControllerIndex', is_array = false, struct = nil}}

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

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

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

function TControllerIndex:unpack(_)
    return self.ControllerIndex
end

PcieAddrInfo.ControllerIndex = TControllerIndex

---@class PcieAddrInfo.ComponentType
---@field ComponentType integer
local TComponentType = {}
TComponentType.__index = TComponentType
TComponentType.group = {}

local function TComponentType_from_obj(obj)
    return setmetatable(obj, TComponentType)
end

function TComponentType.new(ComponentType)
    return TComponentType_from_obj({ComponentType = ComponentType})
end
---@param obj PcieAddrInfo.ComponentType
function TComponentType:init_from_obj(obj)
    self.ComponentType = obj.ComponentType
end

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

TComponentType.from_obj = TComponentType_from_obj

TComponentType.proto_property = {'ComponentType'}

TComponentType.default = {0}

TComponentType.struct = {{name = 'ComponentType', is_array = false, struct = nil}}

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

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

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

function TComponentType:unpack(_)
    return self.ComponentType
end

PcieAddrInfo.ComponentType = TComponentType

---@class PcieAddrInfo.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 PcieAddrInfo.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

PcieAddrInfo.SlotID = TSlotID

---@class PcieAddrInfo.GroupID
---@field GroupID integer
local TGroupID = {}
TGroupID.__index = TGroupID
TGroupID.group = {}

local function TGroupID_from_obj(obj)
    return setmetatable(obj, TGroupID)
end

function TGroupID.new(GroupID)
    return TGroupID_from_obj({GroupID = GroupID})
end
---@param obj PcieAddrInfo.GroupID
function TGroupID:init_from_obj(obj)
    self.GroupID = obj.GroupID
end

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

TGroupID.from_obj = TGroupID_from_obj

TGroupID.proto_property = {'GroupID'}

TGroupID.default = {0}

TGroupID.struct = {{name = 'GroupID', is_array = false, struct = nil}}

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

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

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

function TGroupID:unpack(_)
    return self.GroupID
end

PcieAddrInfo.GroupID = TGroupID

PcieAddrInfo.interface = mdb.register_interface('bmc.kepler.Systems.PcieAddrInfo', {
    GroupID = {'y', nil, true, nil, false},
    SlotID = {'y', nil, true, nil, false},
    ComponentType = {'y', nil, true, nil, false},
    ControllerIndex = {'y', nil, true, nil, false},
    ControllerType = {'y', nil, true, nil, false},
    SocketID = {'y', nil, true, nil, false},
    Segment = {'y', nil, true, nil, false},
    Bus = {'y', nil, true, nil, false},
    Device = {'y', nil, true, nil, false},
    Function = {'y', nil, true, nil, false},
    VendorID = {'q', nil, true, nil, false},
    DeviceID = {'q', nil, true, nil, false},
    PortID = {'y', nil, true, 255, false},
    Lanes = {'y', {}, true, nil, false},
    PCIeType = {'s', {}, true, nil, false},
    SlotType = {'s', {}, true, nil, false}
}, {}, {})

return PcieAddrInfo
