-- 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 def_types = {}

---@class def_types.IdAndDescription
---@field Id string
---@field Description string
local TIdAndDescription = {}
TIdAndDescription.__index = TIdAndDescription
TIdAndDescription.group = {}

local function TIdAndDescription_from_obj(obj)
    return setmetatable(obj, TIdAndDescription)
end

function TIdAndDescription.new(Id, Description)
    return TIdAndDescription_from_obj({Id = Id, Description = Description})
end
---@param obj def_types.IdAndDescription
function TIdAndDescription:init_from_obj(obj)
    self.Id = obj.Id
    self.Description = obj.Description
end

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

TIdAndDescription.from_obj = TIdAndDescription_from_obj

TIdAndDescription.proto_property = {'Id', 'Description'}

TIdAndDescription.default = {'', ''}

TIdAndDescription.struct = {
    {name = 'Id', is_array = false, struct = nil}, {name = 'Description', is_array = false, struct = nil}
}

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

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

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

function TIdAndDescription:unpack(_)
    return self.Id, self.Description
end

def_types.IdAndDescription = TIdAndDescription

---@class def_types.IPMIChannelConfig
---@field HostId integer
---@field Instance integer
local TIPMIChannelConfig = {}
TIPMIChannelConfig.__index = TIPMIChannelConfig
TIPMIChannelConfig.group = {}

local function TIPMIChannelConfig_from_obj(obj)
    return setmetatable(obj, TIPMIChannelConfig)
end

function TIPMIChannelConfig.new(HostId, Instance)
    return TIPMIChannelConfig_from_obj({HostId = HostId, Instance = Instance})
end
---@param obj def_types.IPMIChannelConfig
function TIPMIChannelConfig:init_from_obj(obj)
    self.HostId = obj.HostId
    self.Instance = obj.Instance
end

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

TIPMIChannelConfig.from_obj = TIPMIChannelConfig_from_obj

TIPMIChannelConfig.proto_property = {'HostId', 'Instance'}

TIPMIChannelConfig.default = {0, 0}

TIPMIChannelConfig.struct = {
    {name = 'HostId', is_array = false, struct = nil}, {name = 'Instance', is_array = false, struct = nil}
}

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

    validate.Optional(prefix .. 'HostId', self.HostId, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Instance', self.Instance, 'uint8', false, errs, need_convert)

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

function TIPMIChannelConfig:unpack(_)
    return self.HostId, self.Instance
end

def_types.IPMIChannelConfig = TIPMIChannelConfig

---@class def_types.BDFConfiguration
---@field PortId integer
---@field ControllerIndex integer
---@field Segment integer
---@field Bus integer
---@field Device integer
---@field Function integer
---@field Type integer
local TBDFConfiguration = {}
TBDFConfiguration.__index = TBDFConfiguration
TBDFConfiguration.group = {}

local function TBDFConfiguration_from_obj(obj)
    return setmetatable(obj, TBDFConfiguration)
end

function TBDFConfiguration.new(PortId, ControllerIndex, Segment, Bus, Device, Function, Type)
    return TBDFConfiguration_from_obj({
        PortId = PortId,
        ControllerIndex = ControllerIndex or 255,
        Segment = Segment,
        Bus = Bus,
        Device = Device,
        Function = Function,
        Type = Type
    })
end
---@param obj def_types.BDFConfiguration
function TBDFConfiguration:init_from_obj(obj)
    self.PortId = obj.PortId
    self.ControllerIndex = obj.ControllerIndex or 255
    self.Segment = obj.Segment
    self.Bus = obj.Bus
    self.Device = obj.Device
    self.Function = obj.Function
    self.Type = obj.Type
end

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

TBDFConfiguration.from_obj = TBDFConfiguration_from_obj

TBDFConfiguration.proto_property = {'PortId', 'ControllerIndex', 'Segment', 'Bus', 'Device', 'Function', 'Type'}

TBDFConfiguration.default = {0, 0, 0, 0, 0, 0, 0}

TBDFConfiguration.struct = {
    {name = 'PortId', is_array = false, struct = nil}, {name = 'ControllerIndex', is_array = false, struct = nil},
    {name = 'Segment', is_array = false, struct = nil}, {name = 'Bus', is_array = false, struct = nil},
    {name = 'Device', is_array = false, struct = nil}, {name = 'Function', is_array = false, struct = nil},
    {name = 'Type', is_array = false, struct = nil}
}

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

    validate.Optional(prefix .. 'PortId', self.PortId, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'ControllerIndex', self.ControllerIndex, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Segment', self.Segment, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Bus', self.Bus, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Device', self.Device, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Function', self.Function, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Type', self.Type, 'uint8', false, errs, need_convert)

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

function TBDFConfiguration:unpack(_)
    return self.PortId, self.ControllerIndex, self.Segment, self.Bus, self.Device, self.Function, self.Type
end

def_types.BDFConfiguration = TBDFConfiguration

---@class def_types.Configuration
---@field UID string
---@field Index integer
---@field SrcPortName string[]
---@field TargetPortID integer[]
---@field Slot integer[]
---@field Device integer[]
---@field Default boolean
---@field BCUIndex integer
local TConfiguration = {}
TConfiguration.__index = TConfiguration
TConfiguration.group = {}

local function TConfiguration_from_obj(obj)
    return setmetatable(obj, TConfiguration)
end

function TConfiguration.new(UID, Index, SrcPortName, TargetPortID, Slot, Device, Default, BCUIndex)
    return TConfiguration_from_obj({
        UID = UID,
        Index = Index,
        SrcPortName = SrcPortName,
        TargetPortID = TargetPortID,
        Slot = Slot,
        Device = Device,
        Default = Default,
        BCUIndex = BCUIndex
    })
end
---@param obj def_types.Configuration
function TConfiguration:init_from_obj(obj)
    self.UID = obj.UID
    self.Index = obj.Index
    self.SrcPortName = obj.SrcPortName
    self.TargetPortID = obj.TargetPortID
    self.Slot = obj.Slot
    self.Device = obj.Device
    self.Default = obj.Default
    self.BCUIndex = obj.BCUIndex
end

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

TConfiguration.from_obj = TConfiguration_from_obj

TConfiguration.proto_property = {'UID', 'Index', 'SrcPortName', 'TargetPortID', 'Slot', 'Device', 'Default', 'BCUIndex'}

TConfiguration.default = {'', 0, {}, {}, {}, {}, false, 0}

TConfiguration.struct = {
    {name = 'UID', is_array = false, struct = nil}, {name = 'Index', is_array = false, struct = nil},
    {name = 'SrcPortName', is_array = true, struct = nil}, {name = 'TargetPortID', is_array = true, struct = nil},
    {name = 'Slot', is_array = true, struct = nil}, {name = 'Device', is_array = true, struct = nil},
    {name = 'Default', is_array = false, struct = nil}, {name = 'BCUIndex', is_array = false, struct = nil}
}

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

    validate.Optional(prefix .. 'UID', self.UID, 'string', false, errs, need_convert)
    validate.Optional(prefix .. 'Index', self.Index, 'uint8', false, errs, need_convert)
    validate.OptionalArray(prefix .. 'SrcPortName', self.SrcPortName, 'string', false, errs, need_convert)
    validate.OptionalArray(prefix .. 'TargetPortID', self.TargetPortID, 'uint8', false, errs, need_convert)
    validate.OptionalArray(prefix .. 'Slot', self.Slot, 'uint8', false, errs, need_convert)
    validate.OptionalArray(prefix .. 'Device', self.Device, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Default', self.Default, 'bool', false, errs, need_convert)
    validate.Optional(prefix .. 'BCUIndex', self.BCUIndex, 'uint8', false, errs, need_convert)

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

function TConfiguration:unpack(_)
    return self.UID, self.Index, self.SrcPortName, self.TargetPortID, self.Slot, self.Device, self.Default,
        self.BCUIndex
end

def_types.Configuration = TConfiguration

---@class def_types.PortConfig
---@field ControllerIndex integer[]
---@field PortList integer[]
local TPortConfig = {}
TPortConfig.__index = TPortConfig
TPortConfig.group = {}

local function TPortConfig_from_obj(obj)
    return setmetatable(obj, TPortConfig)
end

function TPortConfig.new(ControllerIndex, PortList)
    return TPortConfig_from_obj({ControllerIndex = ControllerIndex, PortList = PortList})
end
---@param obj def_types.PortConfig
function TPortConfig:init_from_obj(obj)
    self.ControllerIndex = obj.ControllerIndex
    self.PortList = obj.PortList
end

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

TPortConfig.from_obj = TPortConfig_from_obj

TPortConfig.proto_property = {'ControllerIndex', 'PortList'}

TPortConfig.default = {{}, {}}

TPortConfig.struct = {
    {name = 'ControllerIndex', is_array = true, struct = nil}, {name = 'PortList', is_array = true, struct = nil}
}

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

    validate.OptionalArray(prefix .. 'ControllerIndex', self.ControllerIndex, 'uint8', false, errs, need_convert)
    validate.OptionalArray(prefix .. 'PortList', self.PortList, 'uint8', false, errs, need_convert)

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

function TPortConfig:unpack(_)
    return self.ControllerIndex, self.PortList
end

def_types.PortConfig = TPortConfig

---@class def_types.SerdesModeConfig
---@field Mode integer
---@field Device integer[]
---@field ControllerIndex integer[]
---@field DieId integer
---@field StartPfId integer
local TSerdesModeConfig = {}
TSerdesModeConfig.__index = TSerdesModeConfig
TSerdesModeConfig.group = {}

local function TSerdesModeConfig_from_obj(obj)
    return setmetatable(obj, TSerdesModeConfig)
end

function TSerdesModeConfig.new(Mode, Device, ControllerIndex, DieId, StartPfId)
    return TSerdesModeConfig_from_obj({
        Mode = Mode,
        Device = Device,
        ControllerIndex = ControllerIndex,
        DieId = DieId,
        StartPfId = StartPfId
    })
end
---@param obj def_types.SerdesModeConfig
function TSerdesModeConfig:init_from_obj(obj)
    self.Mode = obj.Mode
    self.Device = obj.Device
    self.ControllerIndex = obj.ControllerIndex
    self.DieId = obj.DieId
    self.StartPfId = obj.StartPfId
end

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

TSerdesModeConfig.from_obj = TSerdesModeConfig_from_obj

TSerdesModeConfig.proto_property = {'Mode', 'Device', 'ControllerIndex', 'DieId', 'StartPfId'}

TSerdesModeConfig.default = {0, {}, {}, 0, 0}

TSerdesModeConfig.struct = {
    {name = 'Mode', is_array = false, struct = nil}, {name = 'Device', is_array = true, struct = nil},
    {name = 'ControllerIndex', is_array = true, struct = nil}, {name = 'DieId', is_array = false, struct = nil},
    {name = 'StartPfId', is_array = false, struct = nil}
}

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

    validate.Optional(prefix .. 'Mode', self.Mode, 'uint8', false, errs, need_convert)
    validate.OptionalArray(prefix .. 'Device', self.Device, 'uint8', false, errs, need_convert)
    validate.OptionalArray(prefix .. 'ControllerIndex', self.ControllerIndex, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'DieId', self.DieId, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'StartPfId', self.StartPfId, 'uint8', false, errs, need_convert)

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

function TSerdesModeConfig:unpack(_)
    return self.Mode, self.Device, self.ControllerIndex, self.DieId, self.StartPfId
end

def_types.SerdesModeConfig = TSerdesModeConfig

---@class def_types.Port
---@field Name string
---@field ID integer
---@field Offset integer
---@field Width integer
local TPort = {}
TPort.__index = TPort
TPort.group = {}

local function TPort_from_obj(obj)
    return setmetatable(obj, TPort)
end

function TPort.new(Name, ID, Offset, Width)
    return TPort_from_obj({Name = Name, ID = ID, Offset = Offset, Width = Width})
end
---@param obj def_types.Port
function TPort:init_from_obj(obj)
    self.Name = obj.Name
    self.ID = obj.ID
    self.Offset = obj.Offset
    self.Width = obj.Width
end

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

TPort.from_obj = TPort_from_obj

TPort.proto_property = {'Name', 'ID', 'Offset', 'Width'}

TPort.default = {'', 0, 0, 0}

TPort.struct = {
    {name = 'Name', is_array = false, struct = nil}, {name = 'ID', is_array = false, struct = nil},
    {name = 'Offset', is_array = false, struct = nil}, {name = 'Width', is_array = false, struct = nil}
}

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

    validate.Optional(prefix .. 'Name', self.Name, 'string', false, errs, need_convert)
    validate.Optional(prefix .. 'ID', self.ID, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Offset', self.Offset, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Width', self.Width, 'uint8', false, errs, need_convert)

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

function TPort:unpack(_)
    return self.Name, self.ID, self.Offset, self.Width
end

def_types.Port = TPort

return def_types
