-- Copyright (c) 2026 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 DataSync = {}

---@class DataSync.GetPropertiesReq
---@field Identifier integer
---@field ObjectName string
---@field Interface string
local TGetPropertiesReq = {}
TGetPropertiesReq.__index = TGetPropertiesReq
TGetPropertiesReq.group = {}

local function TGetPropertiesReq_from_obj(obj)
    return setmetatable(obj, TGetPropertiesReq)
end

function TGetPropertiesReq.new(Identifier, ObjectName, Interface)
    return TGetPropertiesReq_from_obj({Identifier = Identifier, ObjectName = ObjectName, Interface = Interface})
end
---@param obj DataSync.GetPropertiesReq
function TGetPropertiesReq:init_from_obj(obj)
    self.Identifier = obj.Identifier
    self.ObjectName = obj.ObjectName
    self.Interface = obj.Interface
end

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

TGetPropertiesReq.from_obj = TGetPropertiesReq_from_obj

TGetPropertiesReq.proto_property = {'Identifier', 'ObjectName', 'Interface'}

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

TGetPropertiesReq.struct = {
    {name = 'Identifier', is_array = false, struct = nil}, {name = 'ObjectName', is_array = false, struct = nil},
    {name = 'Interface', is_array = false, struct = nil}
}

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

    validate.Optional(prefix .. 'Identifier', self.Identifier, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'ObjectName', self.ObjectName, 'string', false, errs, need_convert)
    validate.Optional(prefix .. 'Interface', self.Interface, 'string', false, errs, need_convert)

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

function TGetPropertiesReq:unpack(_)
    return self.Identifier, self.ObjectName, self.Interface
end

DataSync.GetPropertiesReq = TGetPropertiesReq

---@class DataSync.PropertyAttribute
---@field key string
---@field value string
local TPropertyAttribute = {}
TPropertyAttribute.__index = TPropertyAttribute
TPropertyAttribute.group = {}

local function TPropertyAttribute_from_obj(obj)
    return setmetatable(obj, TPropertyAttribute)
end

function TPropertyAttribute.new(dict)
    return TPropertyAttribute_from_obj(dict)
end

---@param obj DataSync.PropertyAttribute
function TPropertyAttribute:init_from_obj(obj)
    self = obj
end

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

TPropertyAttribute.from_obj = TPropertyAttribute_from_obj

TPropertyAttribute.proto_property = {}

TPropertyAttribute.default = {}

TPropertyAttribute.struct = {}

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

    for k, v in pairs(self) do

        validate.Optional(prefix .. 'key', k, 'string', false, errs, need_convert)

        validate.Optional(prefix .. 'value', v, 'string', false, errs, need_convert)

    end

    TPropertyAttribute:remove_error_props(errs, self)
    return self
end

function TPropertyAttribute:unpack(_)
    return self
end

DataSync.PropertyAttribute = TPropertyAttribute

---@class DataSync.PropertyDetail
---@field PropertyName string
---@field PropertyItems DataSync.PropertyAttribute
local TPropertyDetail = {}
TPropertyDetail.__index = TPropertyDetail
TPropertyDetail.group = {}

local function TPropertyDetail_from_obj(obj)
    return setmetatable(obj, TPropertyDetail)
end

function TPropertyDetail.new(PropertyName, PropertyItems)
    return TPropertyDetail_from_obj({PropertyName = PropertyName, PropertyItems = PropertyItems})
end
---@param obj DataSync.PropertyDetail
function TPropertyDetail:init_from_obj(obj)
    self.PropertyName = obj.PropertyName
    self.PropertyItems = obj.PropertyItems
end

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

TPropertyDetail.from_obj = TPropertyDetail_from_obj

TPropertyDetail.proto_property = {'PropertyName', 'PropertyItems'}

TPropertyDetail.default = {'', DataSync.PropertyAttribute.default}

TPropertyDetail.struct = {
    {name = 'PropertyName', is_array = false, struct = nil},
    {name = 'PropertyItems', is_array = false, struct = DataSync.PropertyAttribute.struct}
}

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

    DataSync.PropertyAttribute.new(self.PropertyItems):validate(prefix, errs, need_convert)

    validate.Optional(prefix .. 'PropertyName', self.PropertyName, 'string', false, errs, need_convert)

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

function TPropertyDetail:unpack(_)
    return self.PropertyName, self.PropertyItems
end

DataSync.PropertyDetail = TPropertyDetail

---@class DataSync.SyncProperties
---@field Identifier integer
---@field PropertyDetails DataSync.PropertyDetail[]
local TSyncProperties = {}
TSyncProperties.__index = TSyncProperties
TSyncProperties.group = {}

local function TSyncProperties_from_obj(obj)
    obj.PropertyDetails = utils.from_obj(DataSync.PropertyDetail, obj.PropertyDetails, true)
    return setmetatable(obj, TSyncProperties)
end

function TSyncProperties.new(Identifier, PropertyDetails)
    return TSyncProperties_from_obj({Identifier = Identifier, PropertyDetails = PropertyDetails})
end
---@param obj DataSync.SyncProperties
function TSyncProperties:init_from_obj(obj)
    self.Identifier = obj.Identifier
    self.PropertyDetails = obj.PropertyDetails
end

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

TSyncProperties.from_obj = TSyncProperties_from_obj

TSyncProperties.proto_property = {'Identifier', 'PropertyDetails'}

TSyncProperties.default = {0, {}}

TSyncProperties.struct = {
    {name = 'Identifier', is_array = false, struct = nil},
    {name = 'PropertyDetails', is_array = true, struct = DataSync.PropertyDetail.struct}
}

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

    for _, v in pairs(self.PropertyDetails) do
        DataSync.PropertyDetail.new(v.PropertyName, v.PropertyItems):validate(prefix, errs, need_convert)
    end

    validate.Optional(prefix .. 'Identifier', self.Identifier, 'uint8', false, errs, need_convert)

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

function TSyncProperties:unpack(raw)
    return self.Identifier, utils.unpack(raw, self.PropertyDetails, true)
end

DataSync.SyncProperties = TSyncProperties

---@class DataSync.GetPropertiesRsp
---@field Properties DataSync.SyncProperties[]
local TGetPropertiesRsp = {}
TGetPropertiesRsp.__index = TGetPropertiesRsp
TGetPropertiesRsp.group = {}

local function TGetPropertiesRsp_from_obj(obj)
    obj.Properties = utils.from_obj(DataSync.SyncProperties, obj.Properties, true)
    return setmetatable(obj, TGetPropertiesRsp)
end

function TGetPropertiesRsp.new(Properties)
    return TGetPropertiesRsp_from_obj({Properties = Properties})
end
---@param obj DataSync.GetPropertiesRsp
function TGetPropertiesRsp:init_from_obj(obj)
    self.Properties = obj.Properties
end

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

TGetPropertiesRsp.from_obj = TGetPropertiesRsp_from_obj

TGetPropertiesRsp.proto_property = {'Properties'}

TGetPropertiesRsp.default = {{}}

TGetPropertiesRsp.struct = {{name = 'Properties', is_array = true, struct = DataSync.SyncProperties.struct}}

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

    for _, v in pairs(self.Properties) do
        DataSync.SyncProperties.new(v.Identifier, v.PropertyDetails):validate(prefix, errs, need_convert)
    end

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

function TGetPropertiesRsp:unpack(raw)
    return utils.unpack(raw, self.Properties, true)
end

DataSync.GetPropertiesRsp = TGetPropertiesRsp

DataSync.interface = mdb.register_interface('bmc.kepler.Managers.DataSync', {}, {
    GetProperties = {'a{ss}yss', 'a(ya(sa{ss}))', TGetPropertiesReq, TGetPropertiesRsp}
}, {PropertyUpdated = 'a{ss}yss'})

return DataSync
