-- 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 msg = {}
local defs = {}

---@class defs.ProtocolStruct
---@field Name string
---@field ProtocolType string
---@field DefaultPorts integer[]
---@field PortShareWith string
---@field PortShareFrom string
local TProtocolStruct = {}
TProtocolStruct.__index = TProtocolStruct
TProtocolStruct.group = {}

local function TProtocolStruct_from_obj(obj)
    return setmetatable(obj, TProtocolStruct)
end

function TProtocolStruct.new(Name, ProtocolType, DefaultPorts, PortShareWith, PortShareFrom)
    return TProtocolStruct_from_obj({
        Name = Name,
        ProtocolType = ProtocolType,
        DefaultPorts = DefaultPorts,
        PortShareWith = PortShareWith,
        PortShareFrom = PortShareFrom
    })
end
---@param obj defs.ProtocolStruct
function TProtocolStruct:init_from_obj(obj)
    self.Name = obj.Name
    self.ProtocolType = obj.ProtocolType
    self.DefaultPorts = obj.DefaultPorts
    self.PortShareWith = obj.PortShareWith
    self.PortShareFrom = obj.PortShareFrom
end

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

TProtocolStruct.from_obj = TProtocolStruct_from_obj

TProtocolStruct.proto_property = {
    'Name', 'ProtocolType', 'DefaultPorts', 'PortShareWith', 'PortShareFrom'
}

TProtocolStruct.default = {'', '', {}, '', ''}

TProtocolStruct.struct = {
    {name = 'Name', is_array = false, struct = nil},
    {name = 'ProtocolType', is_array = false, struct = nil},
    {name = 'DefaultPorts', is_array = true, struct = nil},
    {name = 'PortShareWith', is_array = false, struct = nil},
    {name = 'PortShareFrom', is_array = false, struct = nil}
}

function TProtocolStruct:validate(prefix, errs)
    prefix = prefix or ''

    validate.Required(prefix .. 'Name', self.Name, 'string', false, errs)
    validate.Required(prefix .. 'ProtocolType', self.ProtocolType, 'string', false, errs)
    validate.RequiredArray(prefix .. 'DefaultPorts', self.DefaultPorts, 'uint16', false, errs)
    validate.Required(prefix .. 'PortShareWith', self.PortShareWith, 'string', false, errs)
    validate.Required(prefix .. 'PortShareFrom', self.PortShareFrom, 'string', false, errs)

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

function TProtocolStruct:unpack(_)
    return self.Name, self.ProtocolType, self.DefaultPorts, self.PortShareWith, self.PortShareFrom
end

defs.ProtocolStruct = TProtocolStruct

---@class NetworkProtocol.RegisterRsp
---@field InnerPorts integer[]
local TRegisterRsp = {}
TRegisterRsp.__index = TRegisterRsp
TRegisterRsp.group = {}

local function TRegisterRsp_from_obj(obj)
    return setmetatable(obj, TRegisterRsp)
end

function TRegisterRsp.new(InnerPorts)
    return TRegisterRsp_from_obj({InnerPorts = InnerPorts})
end
---@param obj NetworkProtocol.RegisterRsp
function TRegisterRsp:init_from_obj(obj)
    self.InnerPorts = obj.InnerPorts
end

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

TRegisterRsp.from_obj = TRegisterRsp_from_obj

TRegisterRsp.proto_property = {'InnerPorts'}

TRegisterRsp.default = {{}}

TRegisterRsp.struct = {{name = 'InnerPorts', is_array = true, struct = nil}}

function TRegisterRsp:validate(prefix, errs)
    prefix = prefix or ''

    validate.RequiredArray(prefix .. 'InnerPorts', self.InnerPorts, 'uint16', false, errs)

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

function TRegisterRsp:unpack(_)
    return self.InnerPorts
end

msg.RegisterRsp = TRegisterRsp

---@class NetworkProtocol.RegisterReq
---@field Protocol defs.ProtocolStruct
local TRegisterReq = {}
TRegisterReq.__index = TRegisterReq
TRegisterReq.group = {}

local function TRegisterReq_from_obj(obj)
    obj.Protocol = utils.from_obj(defs.ProtocolStruct, obj.Protocol)
    return setmetatable(obj, TRegisterReq)
end

function TRegisterReq.new(Protocol)
    return TRegisterReq_from_obj({Protocol = Protocol})
end
---@param obj NetworkProtocol.RegisterReq
function TRegisterReq:init_from_obj(obj)
    self.Protocol = obj.Protocol
end

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

TRegisterReq.from_obj = TRegisterReq_from_obj

TRegisterReq.proto_property = {'Protocol'}

TRegisterReq.default = {defs.ProtocolStruct.default}

TRegisterReq.struct = {{name = 'Protocol', is_array = false, struct = defs.ProtocolStruct.struct}}

function TRegisterReq:validate(prefix, errs)
    prefix = prefix or ''

    validate.Required(prefix .. 'Protocol', self.Protocol, 'defs.ProtocolStruct', false, errs)

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

function TRegisterReq:unpack(raw)
    return utils.unpack(raw, self.Protocol)
end

msg.RegisterReq = TRegisterReq

local NetworkProtocol = {}

local Mdb = require 'mc.mdb'

---@class NetworkProtocol: Table
NetworkProtocol.NetworkProtocol = Mdb.register_interface('bmc.kepler.Managers.NetworkProtocol', {},
    {Register = {'a{ss}(ssaqss)', 'aq', msg.RegisterReq, msg.RegisterRsp}}, {})
return NetworkProtocol
