-- 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 menu_node = require 'domain.config.MenuNode'
local menu_config = require 'domain.config.Config'
local json = require 'cjson'
local bs_util = require 'util.base_util'
local lu = require 'luaunit'
local project_dir = os.getenv('PROJECT_DIR')
TestConfig = {}

function TestConfig:test_insert_node()
    local node = menu_node.new()
    node:insert({'AdvancedMenu', 'MemoryConfiguration'}, 1)
    node:insert({'AdvancedMenu', 'MemoryConfiguration', 'CpuRASConfiguration'}, 1)
    node:insert({'BootMenu', 'NetworkBootConfiguration'}, 1)
    node:insert({'BootMenu', 'NetworkBootConfiguration', 'PxeBootConfiguration'}, 1)
    local cfg_tbl = json.json_object_new_array()
    node:traverse(cfg_tbl)
    lu.assertEquals(json.json_object_ordered_encode(cfg_tbl),
        '[{"SubMenu":[{"SubMenu":[{"SubMenu":[],"ReadOnly":false,"Attributes":[],' ..
        '"Name":"CpuRASConfiguration"}],"Attributes":[],"Name":"MemoryConfiguration"}],' ..
        '"Attributes":[],"Name":"AdvancedMenu"},{"SubMenu":[{"SubMenu":[{"SubMenu":[],' ..
        '"ReadOnly":false,"Attributes":[],"Name":"PxeBootConfiguration"}],"Attributes":[],' ..
        '"Name":"NetworkBootConfiguration"}],"Attributes":[],"Name":"BootMenu"}]')
end

function TestConfig:test_clear_value()
    local node = menu_node.new()
    node:insert({'AdvancedMenu', 'MemoryConfiguration'}, 1)
    node:insert({'AdvancedMenu', 'MemoryConfiguration', 'CpuRASConfiguration'}, 1)
    local attr = json.json_object_new_object()
    attr.AttributeName = 'EnableSMMU'
    attr.Hidden = true
    attr.Immutable = false
    attr.ReadOnly = false
    node:add_attribute({'AdvancedMenu'}, 1, attr)
    node:clear_value({'AdvancedMenu'}, 1, 'EnableSMMU')
    local cfg_tbl = json.json_object_new_array()
    node:traverse(cfg_tbl)
    lu.assertEquals(json.json_object_ordered_encode(cfg_tbl),
        '[{"SubMenu":[{"SubMenu":[{"SubMenu":[],"ReadOnly":false,"Attributes":[],' ..
        '"Name":"CpuRASConfiguration"}],"Attributes":[],"Name":"MemoryConfiguration"}' ..
        '],"Attributes":[{"AttributeName":"EnableSMMU","Hidden":true,"Immutable":false,' ..
        '"ReadOnly":false,"SettingValue":null,"DefaultHidden":true,"DefaultImmutable":false,' ..
        '"DefaultReadOnly":false}],"Name":"AdvancedMenu"}]'
    )
end

function TestConfig:test_add_attribute()
    local node = menu_node.new()
    node:insert({'AdvancedMenu', 'MemoryConfiguration'}, 1)
    node:insert({'AdvancedMenu', 'MemoryConfiguration', 'CpuRASConfiguration'}, 1)
    local attr = json.json_object_new_object()
    attr.AttributeName = 'EnableSMMU'
    node:add_attribute({'AdvancedMenu'}, 1, attr)
    local cfg_tbl = json.json_object_new_array()
    node:traverse(cfg_tbl)
    lu.assertEquals(json.json_object_ordered_encode(cfg_tbl),
        '[{"SubMenu":[{"SubMenu":[{"SubMenu":[],"ReadOnly":false,"Attributes":[],' ..
        '"Name":"CpuRASConfiguration"}],"Attributes":[],"Name":"MemoryConfiguration"}' ..
        '],"Attributes":[{"AttributeName":"EnableSMMU","SettingValue":null}],"Name":"AdvancedMenu"}]'
    )
    node:clear_value({'AdvancedMenu', 'MemoryConfiguration'}, 1, 'EnableSMMU')
end

function TestConfig:test_update_value()
    local node = menu_node.new()
    node:insert({'AdvancedMenu', 'MemoryConfiguration'}, 1)
    node:insert({'AdvancedMenu', 'MemoryConfiguration', 'CpuRASConfiguration'}, 1)
    local attr = json.json_object_new_object()
    attr.AttributeName = 'EnableSMMU'
    node:add_attribute({'AdvancedMenu'}, 1, attr)
    local cfg_tbl = json.json_object_new_array()
    node:traverse(cfg_tbl)
    lu.assertEquals(json.json_object_ordered_encode(cfg_tbl),
        '[{"SubMenu":[{"SubMenu":[{"SubMenu":[],"ReadOnly":false,"Attributes":[],' ..
        '"Name":"CpuRASConfiguration"}],"Attributes":[],"Name":"MemoryConfiguration"}' ..
        '],"Attributes":[{"AttributeName":"EnableSMMU","SettingValue":null}],"Name":"AdvancedMenu"}]'
    )
    node:update_value({'AdvancedMenu'}, 1, {
        attribute_name = 'EnableSMMU',
        attribute_prop = 'SettingValue',
        attribute_value = 66
    })
    cfg_tbl = json.json_object_new_array()
    node:traverse(cfg_tbl)
    lu.assertEquals(json.json_object_ordered_encode(cfg_tbl),
        '[{"SubMenu":[{"SubMenu":[{"SubMenu":[],"ReadOnly":false,"Attributes":[],' ..
        '"Name":"CpuRASConfiguration"}],"Attributes":[],"Name":"MemoryConfiguration"}' ..
        '],"Attributes":[{"AttributeName":"EnableSMMU","SettingValue":66}],"Name":"AdvancedMenu"}]'
    )
end

function TestConfig:test_config()
    local config = menu_config.new(project_dir .. '/test/test_data/registry.json',
        project_dir .. '/test/test_data/setting.json')
    local cfg_tbl = json.json_object_new_array()
    config:update_value({
        attribute_name = 'DDRDebugLevel',
        attribute_prop = 'CurrentValue',
        attribute_value = 'Maximum'
    })
    config:update_value({
        attribute_name = 'EnableSMMU',
        attribute_prop = 'SettingValue',
        attribute_value = 'Disabled'
    })
    config:update_current_value_by_file()
    config:update_setting_value_by_file()
    config:clear_setting_value()
    config:clear_current_value()
    config:traverse(cfg_tbl)
    local file = io.open('config.json', 'w')
    file:write(json.json_object_ordered_encode(cfg_tbl))
    os.execute('rm -rf ./config.json')
end
