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

---@class NVMeSMART.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})
end
---@param obj NVMeSMART.Status
function TStatus:init_from_obj(obj)
    self.Status = obj.Status
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

NVMeSMART.Status = TStatus

---@class NVMeSMART.UsedPercentage
---@field UsedPercentage integer
local TUsedPercentage = {}
TUsedPercentage.__index = TUsedPercentage
TUsedPercentage.group = {}

local function TUsedPercentage_from_obj(obj)
    return setmetatable(obj, TUsedPercentage)
end

function TUsedPercentage.new(UsedPercentage)
    return TUsedPercentage_from_obj({UsedPercentage = UsedPercentage})
end
---@param obj NVMeSMART.UsedPercentage
function TUsedPercentage:init_from_obj(obj)
    self.UsedPercentage = obj.UsedPercentage
end

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

TUsedPercentage.from_obj = TUsedPercentage_from_obj

TUsedPercentage.proto_property = {'UsedPercentage'}

TUsedPercentage.default = {0}

TUsedPercentage.struct = {{name = 'UsedPercentage', is_array = false, struct = nil}}

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

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

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

function TUsedPercentage:unpack(_)
    return self.UsedPercentage
end

NVMeSMART.UsedPercentage = TUsedPercentage

---@class NVMeSMART.CriticalWarning
---@field CriticalWarning integer
local TCriticalWarning = {}
TCriticalWarning.__index = TCriticalWarning
TCriticalWarning.group = {}

local function TCriticalWarning_from_obj(obj)
    return setmetatable(obj, TCriticalWarning)
end

function TCriticalWarning.new(CriticalWarning)
    return TCriticalWarning_from_obj({CriticalWarning = CriticalWarning})
end
---@param obj NVMeSMART.CriticalWarning
function TCriticalWarning:init_from_obj(obj)
    self.CriticalWarning = obj.CriticalWarning
end

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

TCriticalWarning.from_obj = TCriticalWarning_from_obj

TCriticalWarning.proto_property = {'CriticalWarning'}

TCriticalWarning.default = {0}

TCriticalWarning.struct = {{name = 'CriticalWarning', is_array = false, struct = nil}}

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

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

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

function TCriticalWarning:unpack(_)
    return self.CriticalWarning
end

NVMeSMART.CriticalWarning = TCriticalWarning

---@class NVMeSMART.AvailableSpare
---@field AvailableSpare integer
local TAvailableSpare = {}
TAvailableSpare.__index = TAvailableSpare
TAvailableSpare.group = {}

local function TAvailableSpare_from_obj(obj)
    return setmetatable(obj, TAvailableSpare)
end

function TAvailableSpare.new(AvailableSpare)
    return TAvailableSpare_from_obj({AvailableSpare = AvailableSpare})
end
---@param obj NVMeSMART.AvailableSpare
function TAvailableSpare:init_from_obj(obj)
    self.AvailableSpare = obj.AvailableSpare
end

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

TAvailableSpare.from_obj = TAvailableSpare_from_obj

TAvailableSpare.proto_property = {'AvailableSpare'}

TAvailableSpare.default = {0}

TAvailableSpare.struct = {{name = 'AvailableSpare', is_array = false, struct = nil}}

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

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

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

function TAvailableSpare:unpack(_)
    return self.AvailableSpare
end

NVMeSMART.AvailableSpare = TAvailableSpare

NVMeSMART.interface = mdb.register_interface('bmc.kepler.Systems.Storage.Drive.NVMe.SMART', {
    AvailableSpare = {'y', {}, true, nil},
    CriticalWarning = {'y', {}, true, nil},
    UsedPercentage = {'y', {}, true, nil},
    Status = {'y', nil, true, nil}
}, {}, {})

return NVMeSMART
