-- 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 lu = require 'luaunit'
local hook_tasks = require 'hook_orm_tasks'
local c_controller = require 'controller.controller_object'
local c_drive = require 'drive.drive_object'
local sml = require 'sml'
local method_misc = require 'method_misc'
local c_volume = require 'volume.volume_object'
local c_array = require 'array.array_object'
local c_battery = require 'battery.battery_object'
local c_battery_collect = require 'battery.battery_collection'

TestRaidInfoUpdate = {}

function TestRaidInfoUpdate:setUp()
    self.tasks = hook_tasks:hook()
end

function TestRaidInfoUpdate:tearDown()
    hook_tasks.unhook()
end

function TestRaidInfoUpdate:test_ctrl_start()
    local ok, _ = pcall(function()
        c_controller.start(c_controller)
    end)
    -- 函数内部没有打桩所以执行结果是false
    lu.assertIsFalse(ok)
    lu.assertEquals(c_controller.first_register_task, true)
    lu.assertEquals(c_controller.tasks_pause, false)
end

function TestRaidInfoUpdate:test_update_volume_info()
    local prefun = sml.get_ctrl_init_state
    local prefun1 = sml.get_ld_info
    -- 场景1
    local volume0 = {
        RefController = 0
    }
    sml.get_ctrl_init_state = function()
        error("mock call failed")
    end
    c_volume.get_volume_info(volume0)
    -- 场景2
    local volume1 = {
        RefController = 0,
    }
    sml.get_ctrl_init_state = function()
        return 2
    end
    sml.get_ld_info = function()
        error(0)
    end
    c_volume.get_volume_info(volume1)
    -- 场景3
    local check_res = 0
    local volume2 = {
        RefController = 0,
        on_update = {
            emit = function()
                check_res = 1
            end
        },
    }
    sml.get_ctrl_init_state = function()
        return 2
    end
    sml.get_ld_info = function()
        return 0
    end
    c_volume.get_volume_info(volume2)
    lu.assertEquals(check_res, 1)
    sml.get_ctrl_init_state = prefun
    sml.get_ld_info = prefun1
end

function TestRaidInfoUpdate:test_update_array_info()
    local prefun = sml.get_ctrl_init_state
    local prefun1 = sml.get_array_info
    -- 场景1
    local array0 = {}
    sml.get_ctrl_init_state = function()
        error("mock call failed")
    end
    c_array.get_array_info(array0)

    -- 场景2
    local array1 = {
        RefControllerId = 0,
        Id = 0
    }
    sml.get_ctrl_init_state = function()
        return 2
    end

    sml.get_array_info = function()
        error(0)
    end
    c_array.get_array_info(array1)

    -- 场景3
    local check_res = 0
    local array2 = {
        RefControllerId = 0,
        Id = 0,
        on_update = {
            emit = function()
                check_res = 1
            end
        },
    }
    sml.get_ctrl_init_state = function()
        return 2
    end
    sml.get_array_info = function()
        return 0
    end
    c_array.get_array_info(array2)
    lu.assertEquals(check_res, 1)
    sml.get_ctrl_init_state = prefun
    sml.get_array_info = prefun1
end

function TestRaidInfoUpdate:test_update_battery_info()
    local prefun = sml.get_ctrl_init_state
    local prefun1 = sml.get_battery_info
    -- 场景0
    local battery = {
        enable_request = false,
        set_default_values = function() end
    }
    c_battery.get_battery_info(battery)
    
    -- 场景1
    local battery0 = {enable_request = true}
    sml.get_ctrl_init_state = function()
        error("mock call failed")
    end
    c_battery.get_battery_info(battery0)

    -- 场景2
    local battery1 = {
        enable_request = true,
        RefController = 0,
        Id = 0
    }
    sml.get_ctrl_init_state = function()
        return 2
    end

    sml.get_battery_info = function()
        error(0)
    end
    c_battery.get_battery_info(battery1)

    -- 场景3
    local check_res = 0
    local battery2 = {
        enable_request = true,
        RefController = 0,
        on_update = {
            emit = function()
                check_res = 1
            end
        },
    }
    sml.get_ctrl_init_state = function()
        return 2
    end
    sml.get_battery_info = function()
        return 0
    end
    c_battery.get_battery_info(battery2)
    lu.assertEquals(check_res, 1)
    sml.get_ctrl_init_state = prefun
    sml.get_battery_info = prefun1
end

function TestRaidInfoUpdate:test_start_battery_task()
    local prefun = c_battery.collection
    local check_res = 0
    c_battery.collection = {
        fold = function(self, cb)
            local mock_obj = {
                get_battery_info = function()
                    check_res = 1
                end
            }
            cb(_, mock_obj, key)
        end
    }
    local task_name = "update battery info task"
    c_battery_collect.start_update_battery_info_task(c_battery_collect)
    self.tasks:run_task(task_name)
    lu.assertEquals(check_res, 1)
    c_battery.collection = prefun
end

function TestRaidInfoUpdate:test_update_drive_smart_info_erro_flow()
    local prefun = sml.get_ctrl_init_state
    local prefun1 = sml.get_pd_sas_smart_info
    -- 场景1
    local drive0 = {
        enable_request = false,
        set_default_values = function() end
    }
    c_drive.update_drive_smart_info(drive0)

    -- 场景2
    local drive1 = {
        enable_request = true
    }
    sml.get_ctrl_init_state = function()
        error("mock call failed")
    end
    c_drive.update_drive_smart_info(drive1)

    -- 场景3
    local drive2 = {
        enable_request = true,
        Protocol = 2,
        RefControllerId = 0
    }
    sml.get_ctrl_init_state = function()
        return 2
    end
    sml.get_pd_sas_smart_info = function()
        error(0)
    end
    c_drive.update_drive_smart_info(drive2)

    -- 场景3
    local check_res = 0
    local drive3 = {
        enable_request = true,
        Protocol = 2,
        RefControllerId = 0,
        on_pd_update_smart = {
            emit = function()
                check_res = 1
            end
        }
    }
    sml.get_ctrl_init_state = function()
        return 2
    end
    sml.get_pd_sas_smart_info = function()
        return {manufacture_data = "AA"}
    end
    c_drive.update_drive_smart_info(drive3)
    lu.assertEquals(check_res, 1)
    sml.get_ctrl_init_state = prefun
    sml.get_pd_sas_smart_info = prefun1
end

function TestRaidInfoUpdate:test_update_drive_info_erro_flow()
    local prefun = sml.get_ctrl_init_state
    local prefun1 = sml.get_pd_info
    local drive1 = {
        enable_request = false,
        set_default_values = function() end

    }
    c_drive.update_drive_common_info(drive1)

    sml.get_ctrl_init_state = function()
        error("mock call failed")
    end
    local drive2 = {
        enable_request = true
    }
    c_drive.update_drive_common_info(drive2)

    sml.get_ctrl_init_state = function()
        return 2
    end
    sml.get_pd_info = function ()
        error(0)
    end
    local drive3 = {
        enable_request = true,
        RefControllerId = 0
    }
    c_drive.update_drive_common_info(drive3)

    sml.get_pd_info = function ()
        return {
            slot_num = 1
        }
    end
    local drive4 = {
        enable_request = true,
        SlotNumber = 0,
        RefControllerId = 0
    }
    c_drive.update_drive_common_info(drive4)

    local check_res = 0
    local drive5 = {
        enable_request = true,
        SlotNumber = 1,
        RefControllerId = 0,
        on_pd_update = {
            emit = function()
                check_res = 1
            end
        }
    }
    c_drive.update_drive_common_info(drive5)
    lu.assertEquals(check_res, 1)
    sml.get_ctrl_init_state = prefun
    sml.get_pd_info = prefun1
end