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

---@class PCIeEndpoint.RspHeaderValidators
---@field key string
---@field value string
local TRspHeaderValidators = {}
TRspHeaderValidators.__index = TRspHeaderValidators
TRspHeaderValidators.group = {}

local function TRspHeaderValidators_from_obj(obj)
    return setmetatable(obj, TRspHeaderValidators)
end

function TRspHeaderValidators.new(dict)
    return TRspHeaderValidators_from_obj(dict)
end

---@param obj PCIeEndpoint.RspHeaderValidators
function TRspHeaderValidators:init_from_obj(obj)
    self = obj
end

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

TRspHeaderValidators.from_obj = TRspHeaderValidators_from_obj

TRspHeaderValidators.proto_property = {}

TRspHeaderValidators.default = {}

TRspHeaderValidators.struct = {}

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

    for k, v in pairs(self) do

        validate.Optional(prefix .. 'key', k, 'string', false, errs, need_convert)

        validate.Optional(prefix .. 'value', v, 'string', false, errs, need_convert)

    end

    TRspHeaderValidators:remove_error_props(errs, self)
    return self
end

function TRspHeaderValidators:unpack(_)
    return self
end

PCIeEndpoint.RspHeaderValidators = TRspHeaderValidators

---@class PCIeEndpoint.ReqHeaderFileds
---@field key string
---@field value string
local TReqHeaderFileds = {}
TReqHeaderFileds.__index = TReqHeaderFileds
TReqHeaderFileds.group = {}

local function TReqHeaderFileds_from_obj(obj)
    return setmetatable(obj, TReqHeaderFileds)
end

function TReqHeaderFileds.new(dict)
    return TReqHeaderFileds_from_obj(dict)
end

---@param obj PCIeEndpoint.ReqHeaderFileds
function TReqHeaderFileds:init_from_obj(obj)
    self = obj
end

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

TReqHeaderFileds.from_obj = TReqHeaderFileds_from_obj

TReqHeaderFileds.proto_property = {}

TReqHeaderFileds.default = {}

TReqHeaderFileds.struct = {}

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

    for k, v in pairs(self) do

        validate.Optional(prefix .. 'key', k, 'string', false, errs, need_convert)

        validate.Optional(prefix .. 'value', v, 'string', false, errs, need_convert)

    end

    TReqHeaderFileds:remove_error_props(errs, self)
    return self
end

function TReqHeaderFileds:unpack(_)
    return self
end

PCIeEndpoint.ReqHeaderFileds = TReqHeaderFileds

---@class PCIeEndpoint.Status
---@field Status integer
local TStatus = {}
TStatus.__index = TStatus
TStatus.group = {}

local function TStatus_from_obj(obj)
    return setmetatable(obj, TStatus)
end

function TStatus.new(Status)
    return TStatus_from_obj({Status = Status or 0})
end
---@param obj PCIeEndpoint.Status
function TStatus:init_from_obj(obj)
    self.Status = obj.Status or 0
end

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

TStatus.from_obj = TStatus_from_obj

TStatus.proto_property = {'Status'}

TStatus.default = {0}

TStatus.struct = {{name = 'Status', is_array = false, struct = nil}}

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

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

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

function TStatus:unpack(_)
    return self.Status
end

PCIeEndpoint.Status = TStatus

---@class PCIeEndpoint.MediumType
---@field MediumType integer
local TMediumType = {}
TMediumType.__index = TMediumType
TMediumType.group = {}

local function TMediumType_from_obj(obj)
    return setmetatable(obj, TMediumType)
end

function TMediumType.new(MediumType)
    return TMediumType_from_obj({MediumType = MediumType or 15})
end
---@param obj PCIeEndpoint.MediumType
function TMediumType:init_from_obj(obj)
    self.MediumType = obj.MediumType or 15
end

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

TMediumType.from_obj = TMediumType_from_obj

TMediumType.proto_property = {'MediumType'}

TMediumType.default = {0}

TMediumType.struct = {{name = 'MediumType', is_array = false, struct = nil}}

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

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

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

function TMediumType:unpack(_)
    return self.MediumType
end

PCIeEndpoint.MediumType = TMediumType

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

PCIeEndpoint.MessageType = TMessageType

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

PCIeEndpoint.TargetPhyAddr = TTargetPhyAddr

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

PCIeEndpoint.TargetEid = TTargetEid

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

PCIeEndpoint.ServiceName = TServiceName

---@class PCIeEndpoint.MessageReceivedSignature
---@field Data integer[]
local TMessageReceivedSignature = {}
TMessageReceivedSignature.__index = TMessageReceivedSignature
TMessageReceivedSignature.group = {}

local function TMessageReceivedSignature_from_obj(obj)
    return setmetatable(obj, TMessageReceivedSignature)
end

function TMessageReceivedSignature.new(Data)
    return TMessageReceivedSignature_from_obj({Data = Data})
end
---@param obj PCIeEndpoint.MessageReceivedSignature
function TMessageReceivedSignature:init_from_obj(obj)
    self.Data = obj.Data
end

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

TMessageReceivedSignature.from_obj = TMessageReceivedSignature_from_obj

TMessageReceivedSignature.proto_property = {'Data'}

TMessageReceivedSignature.default = {{}}

TMessageReceivedSignature.struct = {{name = 'Data', is_array = true, struct = nil}}

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

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

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

function TMessageReceivedSignature:unpack(_)
    return self.Data
end

PCIeEndpoint.MessageReceivedSignature = TMessageReceivedSignature

---@class PCIeEndpoint.OnMessageSignature
---@field Data integer[]
local TOnMessageSignature = {}
TOnMessageSignature.__index = TOnMessageSignature
TOnMessageSignature.group = {}

local function TOnMessageSignature_from_obj(obj)
    return setmetatable(obj, TOnMessageSignature)
end

function TOnMessageSignature.new(Data)
    return TOnMessageSignature_from_obj({Data = Data})
end
---@param obj PCIeEndpoint.OnMessageSignature
function TOnMessageSignature:init_from_obj(obj)
    self.Data = obj.Data
end

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

TOnMessageSignature.from_obj = TOnMessageSignature_from_obj

TOnMessageSignature.proto_property = {'Data'}

TOnMessageSignature.default = {{}}

TOnMessageSignature.struct = {{name = 'Data', is_array = true, struct = nil}}

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

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

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

function TOnMessageSignature:unpack(_)
    return self.Data
end

PCIeEndpoint.OnMessageSignature = TOnMessageSignature

---@class PCIeEndpoint.SendRsp
local TSendRsp = {}
TSendRsp.__index = TSendRsp
TSendRsp.group = {}

local function TSendRsp_from_obj(obj)
    return setmetatable(obj, TSendRsp)
end

function TSendRsp.new()
    return TSendRsp_from_obj({})
end
---@param obj PCIeEndpoint.SendRsp
function TSendRsp:init_from_obj(obj)

end

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

TSendRsp.from_obj = TSendRsp_from_obj

TSendRsp.proto_property = {}

TSendRsp.default = {}

TSendRsp.struct = {}

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

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

function TSendRsp:unpack(_)
end

PCIeEndpoint.SendRsp = TSendRsp

---@class PCIeEndpoint.SendReq
---@field Data integer[]
---@field ReqHeaderFileds PCIeEndpoint.ReqHeaderFileds
local TSendReq = {}
TSendReq.__index = TSendReq
TSendReq.group = {}

local function TSendReq_from_obj(obj)
    return setmetatable(obj, TSendReq)
end

function TSendReq.new(Data, ReqHeaderFileds)
    return TSendReq_from_obj({Data = Data, ReqHeaderFileds = ReqHeaderFileds})
end
---@param obj PCIeEndpoint.SendReq
function TSendReq:init_from_obj(obj)
    self.Data = obj.Data
    self.ReqHeaderFileds = obj.ReqHeaderFileds
end

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

TSendReq.from_obj = TSendReq_from_obj

TSendReq.proto_property = {'Data', 'ReqHeaderFileds'}

TSendReq.default = {{}, PCIeEndpoint.ReqHeaderFileds.default}

TSendReq.struct = {
    {name = 'Data', is_array = true, struct = nil},
    {name = 'ReqHeaderFileds', is_array = false, struct = PCIeEndpoint.ReqHeaderFileds.struct}
}

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

    PCIeEndpoint.ReqHeaderFileds.new(self.ReqHeaderFileds):validate(prefix, errs, need_convert)

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

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

function TSendReq:unpack(_)
    return self.Data, self.ReqHeaderFileds
end

PCIeEndpoint.SendReq = TSendReq

---@class PCIeEndpoint.RequestRsp
---@field Data integer[]
local TRequestRsp = {}
TRequestRsp.__index = TRequestRsp
TRequestRsp.group = {}

local function TRequestRsp_from_obj(obj)
    return setmetatable(obj, TRequestRsp)
end

function TRequestRsp.new(Data)
    return TRequestRsp_from_obj({Data = Data})
end
---@param obj PCIeEndpoint.RequestRsp
function TRequestRsp:init_from_obj(obj)
    self.Data = obj.Data
end

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

TRequestRsp.from_obj = TRequestRsp_from_obj

TRequestRsp.proto_property = {'Data'}

TRequestRsp.default = {{}}

TRequestRsp.struct = {{name = 'Data', is_array = true, struct = nil}}

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

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

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

function TRequestRsp:unpack(_)
    return self.Data
end

PCIeEndpoint.RequestRsp = TRequestRsp

---@class PCIeEndpoint.RequestReq
---@field Data integer[]
---@field TimeoutMs integer
---@field ReqHeaderFileds PCIeEndpoint.ReqHeaderFileds
---@field RspHeaderValidators PCIeEndpoint.RspHeaderValidators
local TRequestReq = {}
TRequestReq.__index = TRequestReq
TRequestReq.group = {}

local function TRequestReq_from_obj(obj)
    return setmetatable(obj, TRequestReq)
end

function TRequestReq.new(Data, TimeoutMs, ReqHeaderFileds, RspHeaderValidators)
    return TRequestReq_from_obj({
        Data = Data,
        TimeoutMs = TimeoutMs,
        ReqHeaderFileds = ReqHeaderFileds,
        RspHeaderValidators = RspHeaderValidators
    })
end
---@param obj PCIeEndpoint.RequestReq
function TRequestReq:init_from_obj(obj)
    self.Data = obj.Data
    self.TimeoutMs = obj.TimeoutMs
    self.ReqHeaderFileds = obj.ReqHeaderFileds
    self.RspHeaderValidators = obj.RspHeaderValidators
end

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

TRequestReq.from_obj = TRequestReq_from_obj

TRequestReq.proto_property = {'Data', 'TimeoutMs', 'ReqHeaderFileds', 'RspHeaderValidators'}

TRequestReq.default = {{}, 0, PCIeEndpoint.ReqHeaderFileds.default, PCIeEndpoint.RspHeaderValidators.default}

TRequestReq.struct = {
    {name = 'Data', is_array = true, struct = nil}, {name = 'TimeoutMs', is_array = false, struct = nil},
    {name = 'ReqHeaderFileds', is_array = false, struct = PCIeEndpoint.ReqHeaderFileds.struct},
    {name = 'RspHeaderValidators', is_array = false, struct = PCIeEndpoint.RspHeaderValidators.struct}
}

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

    PCIeEndpoint.ReqHeaderFileds.new(self.ReqHeaderFileds):validate(prefix, errs, need_convert)
    PCIeEndpoint.RspHeaderValidators.new(self.RspHeaderValidators):validate(prefix, errs, need_convert)

    validate.OptionalArray(prefix .. 'Data', self.Data, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'TimeoutMs', self.TimeoutMs, 'int32', false, errs, need_convert)

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

function TRequestReq:unpack(_)
    return self.Data, self.TimeoutMs, self.ReqHeaderFileds, self.RspHeaderValidators
end

PCIeEndpoint.RequestReq = TRequestReq

PCIeEndpoint.interface = mdb.register_interface('bmc.kepler.Systems.Mctp.PCIeEndpoint', {
    ServiceName = {'s', nil, true, nil, false},
    TargetEid = {'y', nil, true, nil, false},
    TargetPhyAddr = {'q', nil, true, nil, false},
    MessageType = {'y', nil, true, nil, false},
    MediumType = {'y', nil, true, 15, false},
    Status = {'y', {'EMIT_CHANGE'}, true, 0, false}
}, {Request = {'a{ss}ayia{ss}a{ss}', 'ay', TRequestReq, TRequestRsp}, Send = {'a{ss}aya{ss}', '', TSendReq, TSendRsp}},
    {OnMessage = 'a{ss}ay', MessageReceived = 'a{ss}ay'})

return PCIeEndpoint
