-- 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.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},
    TargetEid = {'y', nil, true, nil},
    TargetPhyAddr = {'q', nil, true, nil},
    MessageType = {'y', nil, true, nil},
    MediumType = {'y', nil, true, 15},
    Status = {'y', {['emitsChangedSignal'] = 'true'}, true, 0}
}, {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
