-- Copyright (c) 2026 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 c_logic_self_test = require 'unit_manager.class.unit.self_test.logic_self_test'

TestLogic = {}
function TestLogic:test_update_stop_flag()
    local case = {stop_flag = 0, expect_ret = true}
    c_logic_self_test.update_stop_flag(case, true)
    lu.assertEquals(case.stop_flag, case.expect_ret, string.format("update_stop_flag fail"))
end

function TestLogic:test_update_logic_health_status()
    local test_cases = {
        {
            logic_failcount = 1,
            mds_obj = {
                DebounceCount = 0,
                RefChip = {
                    HealthStatus = 0
                }
            },
            expect_ret = 1
        },
        {
            logic_failcount = 0,
            mds_obj = {
                DebounceCount = 1,
                RefChip = {
                    HealthStatus = 1
                }
            },
            expect_ret = 0
        }
    }
    for _, case in ipairs(test_cases) do
        c_logic_self_test.update_logic_health_status(case)
        lu.assertEquals(case.mds_obj.RefChip.HealthStatus, case.expect_ret, string.format("%s fail", case.mds_obj.name))
    end
end

function TestLogic:test_logic_self_test_process()
    local test_cases = {
        {
            update_failcount = function() end,
            update_logic_health_status = function() end,
            write_length = 1,
            logic_failcount = 0,
            stop_flag = false,
            mds_obj = setmetatable({
                name = "LogicSelfTest_write_fail",
                WriteVal = {85},
                ReadVal = {170},
                DebounceCount = 1,
            }, {
                __newindex = function(_, k, _)  -- 强制让对WriteReg赋值时pcall失败
                    if k == "WriteReg" then
                        error("test WriteReg error sence")
                    end
                end
            })
        },
        {
            update_failcount = function() end,
            update_logic_health_status = function() end,
            write_length = 1,
            logic_failcount = 0,
            stop_flag = false,
            mds_obj = {
                name = "LogicSelfTest_read_fail",
                WriteVal = {85},
                ReadVal = {170},
                WriteReg = 85,
                DebounceCount = 1,
                get_property = function() return nil end -- 强制让读取ReadReg时pcall失败
            }
        },
        {
            update_failcount = function() end,
            update_logic_health_status = function() end,
            write_length = 1,
            logic_failcount = 0,
            stop_flag = false,
            mds_obj = {
                name = "LogicSelfTest_check_fail",
                WriteVal = {85},
                ReadVal = {85}, -- 强制构造校验不通过场景
                WriteReg = nil,
                ReadReg = 170,
                DebounceCount = 1
            }
        },
        {
            update_failcount = function() end,
            update_logic_health_status = function() end,
            write_length = 1,
            logic_failcount = 0,
            stop_flag = false,
            mds_obj = {
                name = "LogicSelfTest_check_success",
                WriteVal = {85},
                ReadVal = {85},
                WriteReg = 85,
                ReadReg = 170,
                DebounceCount = 1
            }
        },
        {
            update_failcount = function() end,
            update_logic_health_status = function() end,
            write_length = 1,
            logic_failcount = 0,
            stop_flag = true,
            mds_obj = {
                name = "LogicSelfTest_stop"
            }
        }
    }
    for _, case in ipairs(test_cases) do 
        c_logic_self_test.logic_self_test_process(case, 1)
        lu.assertEquals(case.logic_failcount, 0, string.format("%s fail", case.mds_obj.name))
    end
end

function TestLogic:test_logic_self_test_check_length()
    local test_cases = {
        {mds_obj = {name = "LogicSelfTest_length_0", WriteVal = {85, 170}, ReadVal = {170, 85}},  expect_ret = true},
        {mds_obj = {name = "LogicSelfTest_length_1", WriteVal = {85, 170}, ReadVal = {170, 85, 85}}, expect_ret = false}
    }
    for _, case in ipairs(test_cases) do
        c_logic_self_test:ctor(case.mds_obj, nil)
        local ok = c_logic_self_test:logic_self_test_check_length()
        lu.assertEquals(ok, case.expect_ret, string.format("%s fail", case.mds_obj.name))
    end
end

function TestLogic:test_logic_start_task()
    local test_cases = {
        {
            logic_self_test_check_length = function() return true end,
            logic_self_test_process = function() end,
            stop_flag = true,
            mds_obj = {name = "LogicSelfTest_length_0", PeriodMs = 10}
        },
        {
            logic_self_test_check_length = function() return false end,
            logic_self_test_process = function() end,
            stop_flag = true,
            mds_obj = {name = "LogicSelfTest_length_0", PeriodMs = 10}
        }
    }
    for _, case in ipairs(test_cases) do
        c_logic_self_test.start_logic_self_test_status_task(case)
        lu.assertEquals(case.stop_flag, true, string.format("%s fail", case.mds_obj.name))
    end
end