-- 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 BitIO.WriteReq
---@field Offset integer
---@field Length integer
---@field Mask integer
---@field InData integer[]
local TWriteReq = {}
TWriteReq.__index = TWriteReq
TWriteReq.group = {}

local function TWriteReq_from_obj(obj)
    return setmetatable(obj, TWriteReq)
end

function TWriteReq.new(Offset, Length, Mask, InData)
    return TWriteReq_from_obj({Offset = Offset, Length = Length, Mask = Mask, InData = InData})
end
---@param obj BitIO.WriteReq
function TWriteReq:init_from_obj(obj)
    self.Offset = obj.Offset
    self.Length = obj.Length
    self.Mask = obj.Mask
    self.InData = obj.InData
end

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

TWriteReq.from_obj = TWriteReq_from_obj

TWriteReq.proto_property = {'Offset', 'Length', 'Mask', 'InData'}

TWriteReq.default = {0, 0, 0, {}}

TWriteReq.struct = {
    {name = 'Offset', is_array = false, struct = nil},
    {name = 'Length', is_array = false, struct = nil},
    {name = 'Mask', is_array = false, struct = nil},
    {name = 'InData', is_array = true, struct = nil}
}

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

    validate.Required(prefix .. 'Offset', self.Offset, 'uint32', false, errs)
    validate.Required(prefix .. 'Length', self.Length, 'uint8', false, errs)
    validate.Required(prefix .. 'Mask', self.Mask, 'uint32', false, errs)
    validate.RequiredArray(prefix .. 'InData', self.InData, 'uint8', false, errs)

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

function TWriteReq:unpack(_)
    return self.Offset, self.Length, self.Mask, self.InData
end

msg.WriteReq = TWriteReq

---@class BitIO.ReadRsp
---@field OutData integer[]
local TReadRsp = {}
TReadRsp.__index = TReadRsp
TReadRsp.group = {}

local function TReadRsp_from_obj(obj)
    return setmetatable(obj, TReadRsp)
end

function TReadRsp.new(OutData)
    return TReadRsp_from_obj({OutData = OutData})
end
---@param obj BitIO.ReadRsp
function TReadRsp:init_from_obj(obj)
    self.OutData = obj.OutData
end

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

TReadRsp.from_obj = TReadRsp_from_obj

TReadRsp.proto_property = {'OutData'}

TReadRsp.default = {{}}

TReadRsp.struct = {{name = 'OutData', is_array = true, struct = nil}}

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

    validate.RequiredArray(prefix .. 'OutData', self.OutData, 'uint8', false, errs)

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

function TReadRsp:unpack(_)
    return self.OutData
end

msg.ReadRsp = TReadRsp

---@class BitIO.ReadReq
---@field Offset integer
---@field Length integer
---@field Mask integer
local TReadReq = {}
TReadReq.__index = TReadReq
TReadReq.group = {}

local function TReadReq_from_obj(obj)
    return setmetatable(obj, TReadReq)
end

function TReadReq.new(Offset, Length, Mask)
    return TReadReq_from_obj({Offset = Offset, Length = Length, Mask = Mask})
end
---@param obj BitIO.ReadReq
function TReadReq:init_from_obj(obj)
    self.Offset = obj.Offset
    self.Length = obj.Length
    self.Mask = obj.Mask
end

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

TReadReq.from_obj = TReadReq_from_obj

TReadReq.proto_property = {'Offset', 'Length', 'Mask'}

TReadReq.default = {0, 0, 0}

TReadReq.struct = {
    {name = 'Offset', is_array = false, struct = nil},
    {name = 'Length', is_array = false, struct = nil},
    {name = 'Mask', is_array = false, struct = nil}
}

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

    validate.Required(prefix .. 'Offset', self.Offset, 'uint32', false, errs)
    validate.Required(prefix .. 'Length', self.Length, 'uint8', false, errs)
    validate.Required(prefix .. 'Mask', self.Mask, 'uint32', false, errs)

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

function TReadReq:unpack(_)
    return self.Offset, self.Length, self.Mask
end

msg.ReadReq = TReadReq

local BitIO = {}

local Mdb = require 'mc.mdb'

---@class BitIO: Table
BitIO.BitIO = Mdb.register_interface('bmc.kepler.Chip.BitIO', {}, {
    Read = {'a{ss}uyu', 'ay', msg.ReadReq, msg.ReadRsp},
    Write = {'a{ss}uyuay', '', msg.WriteReq, nil}
}, {})
return BitIO
