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

---@class Battery.TemperatureCelsius
---@field TemperatureCelsius integer
local TTemperatureCelsius = {}
TTemperatureCelsius.__index = TTemperatureCelsius
TTemperatureCelsius.group = {}

local function TTemperatureCelsius_from_obj(obj)
    return setmetatable(obj, TTemperatureCelsius)
end

function TTemperatureCelsius.new(TemperatureCelsius)
    return TTemperatureCelsius_from_obj({TemperatureCelsius = TemperatureCelsius})
end
---@param obj Battery.TemperatureCelsius
function TTemperatureCelsius:init_from_obj(obj)
    self.TemperatureCelsius = obj.TemperatureCelsius
end

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

TTemperatureCelsius.from_obj = TTemperatureCelsius_from_obj

TTemperatureCelsius.proto_property = {'TemperatureCelsius'}

TTemperatureCelsius.default = {0}

TTemperatureCelsius.struct = {{name = 'TemperatureCelsius', is_array = false, struct = nil}}

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

    validate.Optional(prefix .. 'TemperatureCelsius', self.TemperatureCelsius, 'int16', true, errs, need_convert)

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

function TTemperatureCelsius:unpack(_)
    return self.TemperatureCelsius
end

Battery.TemperatureCelsius = TTemperatureCelsius

---@class Battery.Health
---@field Health integer
local THealth = {}
THealth.__index = THealth
THealth.group = {}

local function THealth_from_obj(obj)
    return setmetatable(obj, THealth)
end

function THealth.new(Health)
    return THealth_from_obj({Health = Health})
end
---@param obj Battery.Health
function THealth:init_from_obj(obj)
    self.Health = obj.Health
end

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

THealth.from_obj = THealth_from_obj

THealth.proto_property = {'Health'}

THealth.default = {0}

THealth.struct = {{name = 'Health', is_array = false, struct = nil}}

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

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

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

function THealth:unpack(_)
    return self.Health
end

Battery.Health = THealth

---@class Battery.HealthStatus
---@field HealthStatus integer
local THealthStatus = {}
THealthStatus.__index = THealthStatus
THealthStatus.group = {}

local function THealthStatus_from_obj(obj)
    return setmetatable(obj, THealthStatus)
end

function THealthStatus.new(HealthStatus)
    return THealthStatus_from_obj({HealthStatus = HealthStatus})
end
---@param obj Battery.HealthStatus
function THealthStatus:init_from_obj(obj)
    self.HealthStatus = obj.HealthStatus
end

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

THealthStatus.from_obj = THealthStatus_from_obj

THealthStatus.proto_property = {'HealthStatus'}

THealthStatus.default = {0}

THealthStatus.struct = {{name = 'HealthStatus', is_array = false, struct = nil}}

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

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

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

function THealthStatus:unpack(_)
    return self.HealthStatus
end

Battery.HealthStatus = THealthStatus

---@class Battery.Fault
---@field Fault integer
local TFault = {}
TFault.__index = TFault
TFault.group = {}

local function TFault_from_obj(obj)
    return setmetatable(obj, TFault)
end

function TFault.new(Fault)
    return TFault_from_obj({Fault = Fault or 255})
end
---@param obj Battery.Fault
function TFault:init_from_obj(obj)
    self.Fault = obj.Fault or 255
end

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

TFault.from_obj = TFault_from_obj

TFault.proto_property = {'Fault'}

TFault.default = {0}

TFault.struct = {{name = 'Fault', is_array = false, struct = nil}}

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

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

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

function TFault:unpack(_)
    return self.Fault
end

Battery.Fault = TFault

---@class Battery.State
---@field State integer
local TState = {}
TState.__index = TState
TState.group = {}

local function TState_from_obj(obj)
    return setmetatable(obj, TState)
end

function TState.new(State)
    return TState_from_obj({State = State})
end
---@param obj Battery.State
function TState:init_from_obj(obj)
    self.State = obj.State
end

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

TState.from_obj = TState_from_obj

TState.proto_property = {'State'}

TState.default = {0}

TState.struct = {{name = 'State', is_array = false, struct = nil}}

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

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

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

function TState:unpack(_)
    return self.State
end

Battery.State = TState

---@class Battery.Name
---@field Name string
local TName = {}
TName.__index = TName
TName.group = {}

local function TName_from_obj(obj)
    return setmetatable(obj, TName)
end

function TName.new(Name)
    return TName_from_obj({Name = Name})
end
---@param obj Battery.Name
function TName:init_from_obj(obj)
    self.Name = obj.Name
end

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

TName.from_obj = TName_from_obj

TName.proto_property = {'Name'}

TName.default = {''}

TName.struct = {{name = 'Name', is_array = false, struct = nil}}

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

    validate.Optional(prefix .. 'Name', self.Name, 'string', true, errs, need_convert)

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

function TName:unpack(_)
    return self.Name
end

Battery.Name = TName

Battery.interface = mdb.register_interface('bmc.kepler.Systems.Storage.Battery', {
    Name = {'s', nil, true, nil},
    State = {'y', nil, true, nil},
    Fault = {'y', nil, true, 255},
    HealthStatus = {'u', {'EMIT_CHANGE'}, true, nil},
    Health = {'y', nil, true, nil},
    TemperatureCelsius = {'n', {'VOLATILE', 'EMIT_CHANGE'}, true, nil}
}, {}, {})

return Battery
