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

---@class PCIeTransport.MessageType
---@field MessageType integer
local TMessageType = {}
TMessageType.__index = TMessageType
TMessageType.group = {}

local function TMessageType_from_obj(obj)
    return setmetatable(obj, TMessageType)
end

function TMessageType.new(MessageType)
    return TMessageType_from_obj({MessageType = MessageType})
end
---@param obj PCIeTransport.MessageType
function TMessageType:init_from_obj(obj)
    self.MessageType = obj.MessageType
end

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

TMessageType.from_obj = TMessageType_from_obj

TMessageType.proto_property = {'MessageType'}

TMessageType.default = {0}

TMessageType.struct = {{name = 'MessageType', is_array = false, struct = nil}}

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

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

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

function TMessageType:unpack(_)
    return self.MessageType
end

PCIeTransport.MessageType = TMessageType

---@class PCIeTransport.TargetPhyAddr
---@field TargetPhyAddr integer
local TTargetPhyAddr = {}
TTargetPhyAddr.__index = TTargetPhyAddr
TTargetPhyAddr.group = {}

local function TTargetPhyAddr_from_obj(obj)
    return setmetatable(obj, TTargetPhyAddr)
end

function TTargetPhyAddr.new(TargetPhyAddr)
    return TTargetPhyAddr_from_obj({TargetPhyAddr = TargetPhyAddr})
end
---@param obj PCIeTransport.TargetPhyAddr
function TTargetPhyAddr:init_from_obj(obj)
    self.TargetPhyAddr = obj.TargetPhyAddr
end

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

TTargetPhyAddr.from_obj = TTargetPhyAddr_from_obj

TTargetPhyAddr.proto_property = {'TargetPhyAddr'}

TTargetPhyAddr.default = {0}

TTargetPhyAddr.struct = {{name = 'TargetPhyAddr', is_array = false, struct = nil}}

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

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

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

function TTargetPhyAddr:unpack(_)
    return self.TargetPhyAddr
end

PCIeTransport.TargetPhyAddr = TTargetPhyAddr

---@class PCIeTransport.TargetEid
---@field TargetEid integer
local TTargetEid = {}
TTargetEid.__index = TTargetEid
TTargetEid.group = {}

local function TTargetEid_from_obj(obj)
    return setmetatable(obj, TTargetEid)
end

function TTargetEid.new(TargetEid)
    return TTargetEid_from_obj({TargetEid = TargetEid})
end
---@param obj PCIeTransport.TargetEid
function TTargetEid:init_from_obj(obj)
    self.TargetEid = obj.TargetEid
end

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

TTargetEid.from_obj = TTargetEid_from_obj

TTargetEid.proto_property = {'TargetEid'}

TTargetEid.default = {0}

TTargetEid.struct = {{name = 'TargetEid', is_array = false, struct = nil}}

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

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

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

function TTargetEid:unpack(_)
    return self.TargetEid
end

PCIeTransport.TargetEid = TTargetEid

---@class PCIeTransport.ServiceName
---@field ServiceName string
local TServiceName = {}
TServiceName.__index = TServiceName
TServiceName.group = {}

local function TServiceName_from_obj(obj)
    return setmetatable(obj, TServiceName)
end

function TServiceName.new(ServiceName)
    return TServiceName_from_obj({ServiceName = ServiceName})
end
---@param obj PCIeTransport.ServiceName
function TServiceName:init_from_obj(obj)
    self.ServiceName = obj.ServiceName
end

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

TServiceName.from_obj = TServiceName_from_obj

TServiceName.proto_property = {'ServiceName'}

TServiceName.default = {''}

TServiceName.struct = {{name = 'ServiceName', is_array = false, struct = nil}}

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

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

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

function TServiceName:unpack(_)
    return self.ServiceName
end

PCIeTransport.ServiceName = TServiceName

PCIeTransport.interface = mdb.register_interface('bmc.kepler.Systems.Mctp.PCIeTransport', {
    ServiceName = {'s', nil, true, nil, false},
    TargetEid = {'y', nil, true, nil, false},
    TargetPhyAddr = {'q', nil, true, nil, false},
    MessageType = {'y', nil, true, nil, false}
}, {}, {})

return PCIeTransport
