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

---@class Status.SingleBitErrorPageCount
---@field SingleBitErrorPageCount integer
local TSingleBitErrorPageCount = {}
TSingleBitErrorPageCount.__index = TSingleBitErrorPageCount
TSingleBitErrorPageCount.group = {}

local function TSingleBitErrorPageCount_from_obj(obj)
    return setmetatable(obj, TSingleBitErrorPageCount)
end

function TSingleBitErrorPageCount.new(SingleBitErrorPageCount)
    return TSingleBitErrorPageCount_from_obj({SingleBitErrorPageCount = SingleBitErrorPageCount})
end
---@param obj Status.SingleBitErrorPageCount
function TSingleBitErrorPageCount:init_from_obj(obj)
    self.SingleBitErrorPageCount = obj.SingleBitErrorPageCount
end

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

TSingleBitErrorPageCount.from_obj = TSingleBitErrorPageCount_from_obj

TSingleBitErrorPageCount.proto_property = {'SingleBitErrorPageCount'}

TSingleBitErrorPageCount.default = {0}

TSingleBitErrorPageCount.struct = {{name = 'SingleBitErrorPageCount', is_array = false, struct = nil}}

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

    validate.Optional(prefix .. 'SingleBitErrorPageCount', self.SingleBitErrorPageCount, 'uint32', true, errs,
        need_convert)

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

function TSingleBitErrorPageCount:unpack(_)
    return self.SingleBitErrorPageCount
end

Status.SingleBitErrorPageCount = TSingleBitErrorPageCount

---@class Status.DoubleBitErrorPageCount
---@field DoubleBitErrorPageCount integer
local TDoubleBitErrorPageCount = {}
TDoubleBitErrorPageCount.__index = TDoubleBitErrorPageCount
TDoubleBitErrorPageCount.group = {}

local function TDoubleBitErrorPageCount_from_obj(obj)
    return setmetatable(obj, TDoubleBitErrorPageCount)
end

function TDoubleBitErrorPageCount.new(DoubleBitErrorPageCount)
    return TDoubleBitErrorPageCount_from_obj({DoubleBitErrorPageCount = DoubleBitErrorPageCount})
end
---@param obj Status.DoubleBitErrorPageCount
function TDoubleBitErrorPageCount:init_from_obj(obj)
    self.DoubleBitErrorPageCount = obj.DoubleBitErrorPageCount
end

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

TDoubleBitErrorPageCount.from_obj = TDoubleBitErrorPageCount_from_obj

TDoubleBitErrorPageCount.proto_property = {'DoubleBitErrorPageCount'}

TDoubleBitErrorPageCount.default = {0}

TDoubleBitErrorPageCount.struct = {{name = 'DoubleBitErrorPageCount', is_array = false, struct = nil}}

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

    validate.Optional(prefix .. 'DoubleBitErrorPageCount', self.DoubleBitErrorPageCount, 'uint32', true, errs,
        need_convert)

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

function TDoubleBitErrorPageCount:unpack(_)
    return self.DoubleBitErrorPageCount
end

Status.DoubleBitErrorPageCount = TDoubleBitErrorPageCount

---@class Status.ResetRequired
---@field ResetRequired integer
local TResetRequired = {}
TResetRequired.__index = TResetRequired
TResetRequired.group = {}

local function TResetRequired_from_obj(obj)
    return setmetatable(obj, TResetRequired)
end

function TResetRequired.new(ResetRequired)
    return TResetRequired_from_obj({ResetRequired = ResetRequired or 255})
end
---@param obj Status.ResetRequired
function TResetRequired:init_from_obj(obj)
    self.ResetRequired = obj.ResetRequired or 255
end

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

TResetRequired.from_obj = TResetRequired_from_obj

TResetRequired.proto_property = {'ResetRequired'}

TResetRequired.default = {0}

TResetRequired.struct = {{name = 'ResetRequired', is_array = false, struct = nil}}

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

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

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

function TResetRequired:unpack(_)
    return self.ResetRequired
end

Status.ResetRequired = TResetRequired

---@class Status.ECCModePendingEnabled
---@field ECCModePendingEnabled integer
local TECCModePendingEnabled = {}
TECCModePendingEnabled.__index = TECCModePendingEnabled
TECCModePendingEnabled.group = {}

local function TECCModePendingEnabled_from_obj(obj)
    return setmetatable(obj, TECCModePendingEnabled)
end

function TECCModePendingEnabled.new(ECCModePendingEnabled)
    return TECCModePendingEnabled_from_obj({ECCModePendingEnabled = ECCModePendingEnabled or 255})
end
---@param obj Status.ECCModePendingEnabled
function TECCModePendingEnabled:init_from_obj(obj)
    self.ECCModePendingEnabled = obj.ECCModePendingEnabled or 255
end

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

TECCModePendingEnabled.from_obj = TECCModePendingEnabled_from_obj

TECCModePendingEnabled.proto_property = {'ECCModePendingEnabled'}

TECCModePendingEnabled.default = {0}

TECCModePendingEnabled.struct = {{name = 'ECCModePendingEnabled', is_array = false, struct = nil}}

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

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

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

function TECCModePendingEnabled:unpack(_)
    return self.ECCModePendingEnabled
end

Status.ECCModePendingEnabled = TECCModePendingEnabled

---@class Status.ECCModeEnabled
---@field ECCModeEnabled integer
local TECCModeEnabled = {}
TECCModeEnabled.__index = TECCModeEnabled
TECCModeEnabled.group = {}

local function TECCModeEnabled_from_obj(obj)
    return setmetatable(obj, TECCModeEnabled)
end

function TECCModeEnabled.new(ECCModeEnabled)
    return TECCModeEnabled_from_obj({ECCModeEnabled = ECCModeEnabled or 255})
end
---@param obj Status.ECCModeEnabled
function TECCModeEnabled:init_from_obj(obj)
    self.ECCModeEnabled = obj.ECCModeEnabled or 255
end

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

TECCModeEnabled.from_obj = TECCModeEnabled_from_obj

TECCModeEnabled.proto_property = {'ECCModeEnabled'}

TECCModeEnabled.default = {0}

TECCModeEnabled.struct = {{name = 'ECCModeEnabled', is_array = false, struct = nil}}

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

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

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

function TECCModeEnabled:unpack(_)
    return self.ECCModeEnabled
end

Status.ECCModeEnabled = TECCModeEnabled

---@class Status.NvLinkInfoItem
---@field LinkStatus string
---@field ReplayErrorCount integer
---@field RecoveryErrorCount integer
---@field FlowControlCRCErrorCount integer
---@field DataCRCErrorCount integer
local TNvLinkInfoItem = {}
TNvLinkInfoItem.__index = TNvLinkInfoItem
TNvLinkInfoItem.group = {}

local function TNvLinkInfoItem_from_obj(obj)
    return setmetatable(obj, TNvLinkInfoItem)
end

function TNvLinkInfoItem.new(LinkStatus, ReplayErrorCount, RecoveryErrorCount, FlowControlCRCErrorCount,
    DataCRCErrorCount)
    return TNvLinkInfoItem_from_obj({
        LinkStatus = LinkStatus,
        ReplayErrorCount = ReplayErrorCount,
        RecoveryErrorCount = RecoveryErrorCount,
        FlowControlCRCErrorCount = FlowControlCRCErrorCount,
        DataCRCErrorCount = DataCRCErrorCount
    })
end
---@param obj Status.NvLinkInfoItem
function TNvLinkInfoItem:init_from_obj(obj)
    self.LinkStatus = obj.LinkStatus
    self.ReplayErrorCount = obj.ReplayErrorCount
    self.RecoveryErrorCount = obj.RecoveryErrorCount
    self.FlowControlCRCErrorCount = obj.FlowControlCRCErrorCount
    self.DataCRCErrorCount = obj.DataCRCErrorCount
end

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

TNvLinkInfoItem.from_obj = TNvLinkInfoItem_from_obj

TNvLinkInfoItem.proto_property = {
    'LinkStatus', 'ReplayErrorCount', 'RecoveryErrorCount', 'FlowControlCRCErrorCount', 'DataCRCErrorCount'
}

TNvLinkInfoItem.default = {'', 0, 0, 0, 0}

TNvLinkInfoItem.struct = {
    {name = 'LinkStatus', is_array = false, struct = nil}, {name = 'ReplayErrorCount', is_array = false, struct = nil},
    {name = 'RecoveryErrorCount', is_array = false, struct = nil},
    {name = 'FlowControlCRCErrorCount', is_array = false, struct = nil},
    {name = 'DataCRCErrorCount', is_array = false, struct = nil}
}

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

    validate.Optional(prefix .. 'LinkStatus', self.LinkStatus, 'string', true, errs, need_convert)
    validate.Optional(prefix .. 'ReplayErrorCount', self.ReplayErrorCount, 'uint32', true, errs, need_convert)
    validate.Optional(prefix .. 'RecoveryErrorCount', self.RecoveryErrorCount, 'uint32', true, errs, need_convert)
    validate.Optional(prefix .. 'FlowControlCRCErrorCount', self.FlowControlCRCErrorCount, 'uint32', true, errs,
        need_convert)
    validate.Optional(prefix .. 'DataCRCErrorCount', self.DataCRCErrorCount, 'uint32', true, errs, need_convert)

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

function TNvLinkInfoItem:unpack(_)
    return self.LinkStatus, self.ReplayErrorCount, self.RecoveryErrorCount, self.FlowControlCRCErrorCount,
        self.DataCRCErrorCount
end

Status.NvLinkInfoItem = TNvLinkInfoItem

---@class Status.NvLinkInfo
---@field NvLinkInfo Status.NvLinkInfoItem[]
local TNvLinkInfo = {}
TNvLinkInfo.__index = TNvLinkInfo
TNvLinkInfo.group = {}

local function TNvLinkInfo_from_obj(obj)
    obj.NvLinkInfo = utils.from_obj(Status.NvLinkInfoItem, obj.NvLinkInfo, true)
    return setmetatable(obj, TNvLinkInfo)
end

function TNvLinkInfo.new(NvLinkInfo)
    return TNvLinkInfo_from_obj({NvLinkInfo = NvLinkInfo})
end
---@param obj Status.NvLinkInfo
function TNvLinkInfo:init_from_obj(obj)
    self.NvLinkInfo = obj.NvLinkInfo
end

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

TNvLinkInfo.from_obj = TNvLinkInfo_from_obj

TNvLinkInfo.proto_property = {'NvLinkInfo'}

TNvLinkInfo.default = {{}}

TNvLinkInfo.struct = {{name = 'NvLinkInfo', is_array = true, struct = Status.NvLinkInfoItem.struct}}

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

    for _, v in pairs(self.NvLinkInfo) do
        Status.NvLinkInfoItem.new(v.LinkStatus, v.ReplayErrorCount, v.RecoveryErrorCount, v.FlowControlCRCErrorCount,
            v.DataCRCErrorCount):validate(prefix, errs, need_convert)
    end

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

function TNvLinkInfo:unpack(raw)
    return utils.unpack(raw, self.NvLinkInfo, true)
end

Status.NvLinkInfo = TNvLinkInfo

Status.interface = mdb.register_interface('bmc.kepler.Systems.Processor.GPU.Status', {
    ECCModeEnabled = {'y', {'EMIT_CHANGE'}, true, 255, false},
    ECCModePendingEnabled = {'y', {'EMIT_CHANGE'}, true, 255, false},
    ResetRequired = {'y', {'EMIT_CHANGE'}, true, 255, false},
    DoubleBitErrorPageCount = {'u', {}, true, nil, false},
    SingleBitErrorPageCount = {'u', {}, true, nil, false},
    NvLinkInfo = {'a(suuuu)', {}, true, nil, false}
}, {}, {})

return Status
