-- 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 abstract_cfg = require 'pojo.config.basic.abstract_configure'
local class = require 'mc.class'
local prop_def = require 'macros.property_def'
local log = require 'mc.logging'

local configure = {}

-- MapFrom对象
local TEnum = class(abstract_cfg)

function TEnum:ctor(cfgs)
    TEnum.super.ctor(self, cfgs)
end

configure.Enum = TEnum

-- Attribute对象
local TAttribute = class(abstract_cfg)

local function json_to_enum_list(attrs)
    if attrs == nil then
        return nil
    end

    local attr_list = {}
    local len = #attrs
    for i = 1, len, 1 do
        local attr_obj = TEnum.new(attrs[i])
        attr_list[i] = attr_obj
    end

    return attr_list
end

function TAttribute:ctor(cfgs)
    if not cfgs then
        return
    end

    TAttribute.super.ctor(self, cfgs)

    self.EnumList = nil
    if type(cfgs[prop_def.REGRIST_PROP_VALUE]) ~= 'userdata' then
        self.EnumList = json_to_enum_list(cfgs[prop_def.REGRIST_PROP_VALUE])
    end
end

function TAttribute:destroy()
    if self.EnumList then
        for _, v in pairs(self.EnumList) do
            v:destroy()
        end
        self.EnumList = nil
    end
    TAttribute.super.destroy(self)
end

function TAttribute:get_enum_list()
    return self.EnumList
end

configure.Attribute = TAttribute

-- Menu对象
local TMenu = class(abstract_cfg)

function TMenu:ctor(cfgs)
    TMenu.super.ctor(self, cfgs)
end

function TMenu:destroy()
    TMenu.super.destroy(self)
end

configure.Menu = TMenu

-- MapFrom对象
local TMapFrom = class(abstract_cfg)

function TMapFrom:ctor(cfgs)
    TMapFrom.super.ctor(self, cfgs)
end

function TMapFrom:destroy()
    TMapFrom.super.destroy(self)
end

function TMapFrom:to_string()
    if not self.Cfgs then
        return ''
    end

    local map_from_attr = string.format("%s",
        self.Cfgs[prop_def.REGRIST_PROP_MAPFORMATTRIBUTE])
    local map_from_value = string.format("%s",
    self.Cfgs[prop_def.REGRIST_PROP_MAPFROMVALUE])
    return ' the value for the property ' .. map_from_attr .. ' is ' ..map_from_value
end

function TMapFrom:get_map_from_condition()
    return ' ' .. string.lower(self.Cfgs[prop_def.REGRIST_PROP_MAPTERMS])
end

function TMapFrom:get_map_from_info()
    if not self.Cfgs then
        log:error("get_map_from_info: cfgs is null.")
        return nil
    end

    local map_from_info = {}
    local map_from_attr = prop_def.REGRIST_PROP_MAPFORMATTRIBUTE
    local map_from_prop = prop_def.REGRIST_PROP_MAPFROMPROPERTY
    local map_from_terms = prop_def.REGRIST_PROP_MAPTERMS
    local map_from_condition = prop_def.REGRIST_PROP_MAPFROMCONDITION
    local map_from_value = prop_def.REGRIST_PROP_MAPFROMVALUE

    local map_from_attr_val = self.Cfgs[map_from_attr]
    if map_from_attr_val == nil then
        log:error("get_map_from_info: map_from_attr_val is null.")
        return nil
    end

    local map_from_prop_val = self.Cfgs[map_from_prop]
    if map_from_prop_val == nil then
        log:error("get_map_from_info: map_from_prop_val is null.")
        return nil
    end

    local map_from_terms_val = self.Cfgs[map_from_terms]
    if map_from_terms_val == nil then
        log:error("get_map_from_info: map_from_terms_val is null.")
        return nil
    end

    local map_from_condition_val = self.Cfgs[map_from_condition]
    if map_from_condition_val == nil then
        log:error("get_map_from_info: map_from_condition_val is null.")
        return nil
    end

    local map_from_value_val = self.Cfgs[map_from_value]
    if map_from_value_val == nil then
        log:error("get_map_from_info: map_from_value_val is null.")
        return nil
    end

    map_from_info[map_from_attr] = map_from_attr_val
    map_from_info[map_from_prop] = map_from_prop_val
    map_from_info[map_from_terms] = map_from_terms_val
    map_from_info[map_from_condition] = map_from_condition_val
    map_from_info[map_from_value] = map_from_value_val

    return map_from_info
end

configure.MapFrom = TMapFrom

-- Dependency对象
local TDependency = class(abstract_cfg)

local function json_to_map_from_list(attrs)
    if attrs == nil then
        return nil
    end

    local attr_list = {}
    local len = #attrs
    for i = 1, len, 1 do
        local attr_obj = TMapFrom.new(attrs[i])
        attr_list[i] = attr_obj
    end

    return attr_list
end

function TDependency:ctor(cfgs)
    TDependency.super.ctor(self, cfgs)
    self.MapFromList = nil
    if type(cfgs[prop_def.REGRIST_PROP_DEPENDENCY][prop_def.REGRIST_PROP_MAPFORM]) ~= 'userdata' then
        self.MapFromList = json_to_map_from_list(
            cfgs[prop_def.REGRIST_PROP_DEPENDENCY][prop_def.REGRIST_PROP_MAPFORM])
    end
end

function TDependency:destroy()
    if self.MapFromList then
        for _, v in pairs(self.MapFromList) do
            v:destroy()
        end
        self.MapFromList = nil
    end
    TDependency.super.destroy(self)
end

function TDependency:get_map_to_attr(map_to_prop)
    if not self.Cfgs or not self.Cfgs[prop_def.REGRIST_PROP_DEPENDENCY] then
        log:error("get_map_to_attr: cfgs is null.")
        return nil
    end

    return self.Cfgs[prop_def.REGRIST_PROP_DEPENDENCY][map_to_prop]
end

function TDependency:get_map_to_info()
    local map_to_attr = prop_def.REGRIST_PROP_MAPTOATTRIBUTE
    local map_to_prop = prop_def.REGRIST_PROP_MAPTOPROPERTY
    local map_to_value = prop_def.REGRIST_PROP_MAPTOVALUE
    local map_to_info = {}
    local map_to_attr_val = self:get_map_to_attr(map_to_attr)
    if map_to_attr_val == nil then
        log:error("get_map_to_info: map_to_attr_val is null.")
        return nil
    end

    local map_to_prop_val = self:get_map_to_attr(map_to_prop)
    if map_to_prop_val == nil then
        log:error("get_map_to_info: map_to_prop_val is null.")
        return nil
    end

    local map_to_value_val = self:get_map_to_attr(map_to_value)
    if map_to_value_val == nil then
        log:error("get_map_to_info: map_to_value_val is null.")
        return nil
    end

    map_to_info[map_to_attr] = map_to_attr_val
    map_to_info[map_to_prop] = map_to_prop_val
    map_to_info[map_to_value] = map_to_value_val
    return map_to_info
end

function TDependency:get_map_from_list()
    return self.MapFromList
end

function TDependency:map_to_string()
    -- 类型为TMapFrom
    local map_from_list = self.MapFromList
    if not map_from_list then
        return ''
    end
    local text = {}
    local index = 1
    for i = 1, #map_from_list do
        local map_from_obj =  map_from_list[i]
        if i > 1 then
            text[index] = map_from_obj:get_map_from_condition()
            index = index + 1
        end
        text[index] = map_from_obj:to_string()
        index = index + 1
    end
    return table.concat(text)
end

configure.Dependency = TDependency

return configure