-- 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 dpu_service = require 'dpu_service.dpu_service'
local lu = require 'luaunit'
local dpu_object = require 'dpu_service.dpu_object'
local file_sec = require 'utils.file'
local utils = require 'dpu_service.utils'
local utils_core = require 'utils.core'
local skynet = require 'skynet'

local COMPUTING_BOARD_PORT0<const> = 3
local COMPUTING_BOARD_PORT1<const> = 4
local COMPUTING_BOARD_PORT2<const> = 5
local LLDP_ENABLE<const> = 1
local LLDP_DISABLE<const> = 0
local LLDP_STATUS_TYPE<const> = 5
local TLV_OS_STATUS<const> = 6
local E_OK = 0 -- 函数执行成功返回0
local E_FAILED = -1

local ILLEGAL_TYPE<const> = 6
TestDpuService = {}

function TestDpuService:setupClass()
end

function TestDpuService:teardownClass()
end


function TestDpuService:test_fetch_dpu_hardware_info()
    local mock = skynet.sleep
    skynet.sleep = function () end
    local obj = {
        fetch_bios_version = function ()
            return 'version'
        end,
        fetch_cpu_arch = function ()
            return 'cpu_arch'
        end,
        fetch_cpu_cores = function ()
            return 'cpu_cores'
        end,
        fetch_disk_size = function ()
            return 'disk_size'
        end,
        fetch_mem_size = function ()
            return 'mem_size'
        end
    }
    local ok, _ = pcall(dpu_service.fetch_dpu_hardware_info, dpu_service, obj)
    lu.assertEquals(ok, true)
    skynet.sleep = mock
end

function TestDpuService:test_is_dpu_mcu()
    local ret = dpu_service:is_dpu_mcu('type', '')
    lu.assertEquals(ret, false)

    local mock1 = utils.get_firmware_uid
    utils.get_firmware_uid =function(...)
        return false
    end
    local ret = dpu_service:is_dpu_mcu('Mcu', '')
    lu.assertEquals(ret, false)

    utils.get_firmware_uid =function(...)
        return true
    end
    local ret = dpu_service:is_dpu_mcu('Mcu', '')
    lu.assertEquals(ret, true)

    utils.get_firmware_uid = mock1
end

function TestDpuService:test_on_upgrade_prepare()
    local mock1 = file_sec.check_real_path_s
    file_sec.check_real_path_s = function()
        return E_FAILED
    end
    local ok, _ = pcall(dpu_service.on_upgrade_prepare, dpu_service, nil, 0, 'DPUCpld', "/tmp/", nil, "param")
    lu.assertEquals(ok, true)

    file_sec.check_real_path_s = function()
        return E_OK
    end
    local mock2 = utils.uncompress_firmware
    utils.uncompress_firmware = function()
        return ''
    end
    local ok, _ = pcall(dpu_service.on_upgrade_prepare, dpu_service, nil, 0, 'DPUCpld', "/tmp/", nil, "param")
    lu.assertEquals(ok, true)

    utils.uncompress_firmware = mock2
    local ok, _ = pcall(dpu_service.on_upgrade_prepare, dpu_service, nil, 0, 'DPUCpld', "/tmp/", nil, "param")
    lu.assertEquals(ok, true)
    file_sec.check_real_path_s = mock1
end

function TestDpuService:test_get_LLDP_status()
    local obj = {path = 'path'}
    local ok, _ = pcall(dpu_service.get_LLDP_status, dpu_service, obj, 'ctx', COMPUTING_BOARD_PORT0)
    lu.assertEquals(ok, false)

    dpu_service.get_dpu_obj_by_path = function()
        return nil
    end
    local ok, _ = pcall(dpu_service.get_LLDP_status, dpu_service, obj, 'ctx', COMPUTING_BOARD_PORT2)
    lu.assertEquals(ok, false)

    dpu_service.get_dpu_obj_by_path = function()
        return {LLDP_status = TLV_OS_STATUS}
    end
    local ok, _ = pcall(dpu_service.get_LLDP_status, dpu_service, obj, 'ctx', COMPUTING_BOARD_PORT2)
    lu.assertEquals(ok, true)
end

function TestDpuService:test_set_LLDP_status()
    local obj = {
        path = 'path'
    }
    local ctx
    local ok, _ = pcall(dpu_service.set_LLDP_status, dpu_service, obj, ctx, COMPUTING_BOARD_PORT0, LLDP_DISABLE)
    lu.assertEquals(ok, false)

    local ok, _ = pcall(dpu_service.set_LLDP_status, dpu_service, obj, ctx, COMPUTING_BOARD_PORT2, LLDP_DISABLE)
    lu.assertEquals(ok, false)

    -- dpu is nill
    dpu_service.get_dpu_obj_by_path = function()
        return nil
    end
    local ok, _ = pcall(dpu_service.set_LLDP_status, dpu_service, obj, ctx, COMPUTING_BOARD_PORT2, LLDP_DISABLE)
    lu.assertEquals(ok, false)

    --call get_dpu_LLDP_status  fail
    dpu_service.get_dpu_obj_by_path = function()
        return {
            get_dpu_LLDP_status = function()
                return nil
            end
        }
    end
    local ok, _ = pcall(dpu_service.set_LLDP_status, dpu_service, obj, ctx, COMPUTING_BOARD_PORT2, LLDP_DISABLE)
    lu.assertEquals(ok, false)

    -- call get_dpu_LLDP_status suc, but value.type is illegal
    dpu_service.get_dpu_obj_by_path = function()
        return {
            get_dpu_LLDP_status = function()
                return true, {type = ILLEGAL_TYPE}
            end
        }
    end
    local ok, _ = pcall(dpu_service.set_LLDP_status, dpu_service, obj, ctx, COMPUTING_BOARD_PORT2, LLDP_DISABLE)
    lu.assertEquals(ok, false)

    -- call get_dpu_LLDP_status suc, and value.type is right
    dpu_service.get_dpu_obj_by_path = function()
        return {
            get_dpu_LLDP_status = function()
                return true, {type = LLDP_STATUS_TYPE, status = LLDP_ENABLE}
            end,
            set_dpu_LLDP_status = function()
                return false, LLDP_ENABLE
            end
        }
    end
    local ok, _ = pcall(dpu_service.set_LLDP_status, dpu_service, obj, ctx, COMPUTING_BOARD_PORT2, LLDP_DISABLE)
    lu.assertEquals(ok, false)

    -- call get_dpu_LLDP_status suc, and value.type is right
    dpu_service.get_dpu_obj_by_path = function()
        return {
            get_dpu_LLDP_status = function()
                return true, {type = LLDP_STATUS_TYPE, status = LLDP_ENABLE}
            end,
            set_dpu_LLDP_status = function()
                return true, LLDP_ENABLE
            end
        }
    end
    local ok, _ = pcall(dpu_service.set_LLDP_status, dpu_service, obj, ctx, COMPUTING_BOARD_PORT1, LLDP_DISABLE)
    lu.assertEquals(ok, true)
end

function TestDpuService:test_set_serial_direction()
    local obj = {
        path = 'path'
    }
    local ctx
    local ok, _ = pcall(dpu_service.set_serial_direction, dpu_service, obj, ctx, 0)
    lu.assertEquals(ok, false)

    dpu_service.get_dpu_obj_by_path = function()
        return nil
    end
    ok, _ = pcall(dpu_service.set_serial_direction, dpu_service, obj, ctx, 1)
    lu.assertEquals(ok, false)
end