-- 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 log = require 'mc.logging'
local json = require 'cjson'
local mc_ctx = require 'mc.context'
local skynet = require 'skynet'

local customize = {}
local ctx = mc_ctx.new('IT', 'Admin', '127.0.0.1')

local function test_config_datas_empty()
    local datas = {
        BMCSet_CustomSerialNUM = {Import = true, Value = 'off'},
        Custom_SerialNUM = {Import = true, Value = ''},
        BMCSet_CustomAssetTag = {Import = true, Value = 'off'},
        Custom_AssetTag = {Import = true, Value = ''},
        BMCSet_MACHINENAME = {Import = true, Value = ''},
        BMCSet_CustomManufacturer = {Import = true, Value = 'off'},
        Custom_Manufacturer = {Import = true, Value = 'Test'},
        BMCSet_CustomBoardPartNumberFlag = {Import = true, Value = 'off'},
        BMCSet_CustomSerialnumSuffix = {Import = true, Value = 'off'},
        Custom_SerialnumSuffixBySlot = {Import = true, Value = ''},
        BMCSet_FRUProductExtraDescription = {Import = true, Value = ''},
        BMCSet_FRUDescription = {Import = true, Value = ''},
        BMCSet_CustomBoardManufacturer = {Import = true, Value = ''},
        BMCSet_CustomProductManufacturer = {Import = true, Value = ''},
        BMCSet_CustomBoardExtendLabel = {Import = true, Value = ''},
        BMCSet_FRUBoardExInfoPcbVer = {Import = true, Value = 'off'},
        BMCSet_CustomChassisPartNumber = {Import = true, Value = 'off'},
        Custom_ChassisPartNumber = {Import = true, Value = ''},
        BMCSet_CustomChassisType = {Import = true, Value = 'off'},
        Custom_ChassisChassisType = {Import = true, Value = 0},
        BMCSet_CustomProductVersion = {Import = true, Value = 'off'},
        Custom_ProductVersion = {Import = true, Value = ''},
        BMCSet_CustomMainboard_BoardManufacturer = {Import = true, Value = 'off'},
        Custom_Mainboard_BoardManufacturer = {Import = true, Value = 'Test'},
        BMCSet_CustomMainboard_ProductManufacturer = {Import = true, Value = 'off'},
        Custom_Mainboard_ProductManufacturer = {Import = true, Value = 'Test'},
        BMCSet_CustomMainboard_ProductName = {Import = true, Value = 'off'},
        Custom_Mainboard_ProductName = {Import = true, Value = ''},
        BMCSet_CustomMainboard_BoardProductName = {Import = true, Value = 'off'},
        Custom_Mainboard_BoardProductName = {Import = true, Value = ''},
        BMCSet_CustomMainboard_ProductSerialNum = {Import = true, Value = 'off'},
        Custom_Mainboard_ProductSerialNum = {Import = true, Value = ''},
        BMCSet_CustomMainboard_ProductPartNum = {Import = true, Value = 'off'},
        Custom_Mainboard_ProductPartNum = {Import = true, Value = ''},
        BMCSet_FRUProductExtraFormat = {Import = true, Value = 0}
    }
    return datas
end

local function test_config_datas()
    local datas = {
        BMCSet_CustomSerialNUM = {Import = true, Value = 'on'},
        Custom_SerialNUM = {Import = true, Value = 'test_Serial'},
        BMCSet_CustomAssetTag = {Import = true, Value = 'on'},
        Custom_AssetTag = {Import = true, Value = 'testTag'},
        BMCSet_MACHINENAME = {Import = true, Value = 'Test 100B'},
        BMCSet_CustomManufacturer = {Import = true, Value = 'on'},
        Custom_Manufacturer = {Import = true, Value = 'Test222'},
        BMCSet_CustomBoardPartNumberFlag = {Import = true, Value = 'on'},
        BMCSet_CustomSerialnumSuffix = {Import = true, Value = 'off'},
        Custom_SerialnumSuffixBySlot = {Import = true, Value = ''},
        BMCSet_FRUProductExtraDescription = {Import = true, Value = 'Test:EXP1'},
        BMCSet_FRUDescription = {Import = true, Value = 'Test:EXP2;TEST=123'},
        BMCSet_CustomBoardManufacturer = {Import = true, Value = 'TestT'},
        BMCSet_CustomProductManufacturer = {Import = true, Value = 'Test123'},
        BMCSet_CustomBoardExtendLabel = {Import = true, Value = 'Test:exp3;Haise=exp4'},
        BMCSet_FRUBoardExInfoPcbVer = {Import = true, Value = 'on'},
        BMCSet_CustomChassisPartNumber = {Import = true, Value = 'on'},
        Custom_ChassisPartNumber = {Import = true, Value = '123456'},
        BMCSet_CustomChassisType = {Import = true, Value = 'on'},
        Custom_ChassisChassisType = {Import = true, Value = 23},
        BMCSet_CustomProductVersion = {Import = true, Value = 'on'},
        Custom_ProductVersion = {Import = true, Value = 'test.106.01'},
        BMCSet_CustomMainboard_ProductName = {Import = true, Value = 'on'},
        Custom_Mainboard_ProductName = {Import = true, Value = 'Test 100B'},
        BMCSet_CustomMainboard_BoardProductName = {Import = true, Value = 'on'},
        Custom_Mainboard_BoardProductName = {Import = true, Value = 'Test 920P'},
        BMCSet_CustomMainboard_ProductSerialNum = {Import = true, Value = 'on'},
        Custom_Mainboard_ProductSerialNum = {Import = true, Value = '789456123'},
        BMCSet_CustomMainboard_ProductPartNum = {Import = true, Value = 'on'},
        Custom_Mainboard_ProductPartNum = {Import = true, Value = '123789456'},
        BMCSet_FRUProductExtraFormat = {Import = true, Value = 1}
    }
    return datas
end

local function test_config_datas_flags()
    local datas = {
        BMCSet_CustomSerialNUM = {Import = true, Value = 'on'},
        Custom_SerialNUM = {Import = true, Value = ''},
        BMCSet_CustomAssetTag = {Import = true, Value = 'on'},
        Custom_AssetTag = {Import = true, Value = ''},
        BMCSet_MACHINENAME = {Import = true, Value = ''},
        BMCSet_CustomManufacturer = {Import = true, Value = 'on'},
        Custom_Manufacturer = {Import = true, Value = 'Test'},
        BMCSet_CustomBoardPartNumberFlag = {Import = true, Value = 'on'},
        BMCSet_CustomSerialnumSuffix = {Import = true, Value = 'off'},
        Custom_SerialnumSuffixBySlot = {Import = true, Value = ''},
        BMCSet_FRUProductExtraDescription = {Import = true, Value = ''},
        BMCSet_FRUDescription = {Import = true, Value = ''},
        BMCSet_CustomBoardManufacturer = {Import = true, Value = ''},
        BMCSet_CustomProductManufacturer = {Import = true, Value = ''},
        BMCSet_CustomBoardExtendLabel = {Import = true, Value = ''},
        BMCSet_FRUBoardExInfoPcbVer = {Import = true, Value = 'on'},
        BMCSet_CustomChassisPartNumber = {Import = true, Value = 'on'},
        Custom_ChassisPartNumber = {Import = true, Value = '123456'},
        BMCSet_CustomChassisType = {Import = true, Value = 'on'},
        Custom_ChassisChassisType = {Import = true, Value = 0},
        BMCSet_CustomProductVersion = {Import = true, Value = 'on'},
        Custom_ProductVersion = {Import = true, Value = ''},
        BMCSet_CustomMainboard_BoardManufacturer = {Import = true, Value = 'on'},
        Custom_Mainboard_BoardManufacturer = {Import = true, Value = 'Test'},
        BMCSet_CustomMainboard_ProductManufacturer = {Import = true, Value = 'on'},
        Custom_Mainboard_ProductManufacturer = {Import = true, Value = 'Test'},
        BMCSet_CustomMainboard_ProductName = {Import = true, Value = 'on'},
        Custom_Mainboard_ProductName = {Import = true, Value = ''},
        BMCSet_CustomMainboard_BoardProductName = {Import = true, Value = 'on'},
        Custom_Mainboard_BoardProductName = {Import = true, Value = ''},
        BMCSet_CustomMainboard_ProductSerialNum = {Import = true, Value = 'on'},
        Custom_Mainboard_ProductSerialNum = {Import = true, Value = ''},
        BMCSet_CustomMainboard_ProductPartNum = {Import = true, Value = 'on'},
        Custom_Mainboard_ProductPartNum = {Import = true, Value = ''},
    }
    return datas
end

local service = 'bmc.kepler.frudata'
local path = '/bmc/kepler/frudata/MicroComponent'
local intf = 'bmc.kepler.MicroComponent.ConfigManage'

local function test_on_import(bus, config_data)
    local data = json.encode( { ConfigData = { CustomSettings = config_data } } )
    bus:call(service, path, intf, 'Import', 'a{ss}ss', ctx, data, 'custom')
end

local function test_on_export(bus, config_data)
    local datas = bus:call(service, path, intf, 'Export', 'a{ss}s', ctx, 'custom')
    local export_data = json.decode(datas)
    local import_data = config_data

    for key, export_value in pairs(export_data.ConfigData.CustomSettings) do
        local import_value = import_data[key].Value
        assert(import_value == export_value,
            string.format('import %s failed, import value(%s), export value(%s)', key, import_value, export_value))
    end
end

local function test_on_verify(bus, import_data)
    local data = json.encode({Components = {frudata = {ConfigData = {CustomSettings = import_data}}}})
    local verify_datas = bus:call(service, path, intf, 'Verify', 'a{ss}s', ctx, data)

    for key, verify_value in pairs(json.decode(verify_datas)) do
        assert(verify_value.Result == 'success' or verify_value.Result == 'none',
            string.format('import %s failed, import value(%s), verify value(%s)',
                key, import_data[key].Value, verify_value.Value))
    end

end

function customize:test_customize(bus)
    log:notice('============== test customize start ==============')

    -- 先跑空定制化
    log:notice('============== test empty customize start ==============')
    test_on_import(bus, test_config_datas_empty())
    test_on_export(bus, test_config_datas_empty())
    test_on_verify(bus, test_config_datas_empty())

    skynet.sleep(50)
    -- 跑flag项的空定制化
    log:notice('============== test flags customize start ==============')
    test_on_import(bus, test_config_datas_flags())
    test_on_export(bus, test_config_datas_flags())
    test_on_verify(bus, test_config_datas_flags())

    skynet.sleep(50)
    -- 再跑满定制化
    log:notice('============== test full customize start ==============')
    test_on_import(bus, test_config_datas())
    test_on_export(bus, test_config_datas())
    test_on_verify(bus, test_config_datas())
    log:notice('============== test customize end ==============')
end

return customize