-- Copyright (c) 2025 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.

TestIPMI = {}
function TestIPMI:test_pp_ipmi_cmd_chassis_ctrl()
    local cls = require 'pwr_powerctrl_ipmi'
    cls.multihost = {
        is_multihost_type = function()
            return false
        end
    }
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    get_ACCycleEnabled = function() return true end,
                    set_restart_channel = function() end
                },
                powerapi = {
                    system_reset = function() end,
                }
            }
        }
    }
    local ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_chassis_ctrl({Cmd = 0x7}, {chan_num = 1, ChanType = 1})
    end)
    assert(ok, rsp)
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_fru_ctrl({PicmgId = 0x00, FruId = 0xff, Option = 0x00}, {HostId = 1})
    end)
    assert(not ok, rsp)
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    get_ACCycleEnabled = function() return false end,
                    set_restart_channel = function() end
                },
                powerapi = {
                    system_reset = function() end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_chassis_ctrl({Cmd = 0x7}, {chan_num = 1, ChanType = 1})
    end)
    assert(not ok, rsp)

    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    power_on_lock = {
                        is_power_locked_by_upgrade =  function() return true end
                    },
                    get_PwrOnLocked = function() return true end
                },
                powerapi = {
                    system_reset = function() end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_chassis_ctrl({Cmd = 0x01}, {HostId = 1})
    end)
    assert(not ok, rsp)
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    power_on_lock = {
                        is_power_locked_by_upgrade =  function() return false end
                    },
                    get_PwrOnLocked = function() return false end,
                    set_restart_channel = function() end
                },
                powerapi = {
                        system_reset = function() end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_chassis_ctrl({Cmd = 0x04}, {HostId = 1, ChanType = 1})
    end)
    assert(ok, rsp)

    cls.fructrl_obj_mgnt.host_obj[1].powerapi.system_reset = function() error() end
    cls.fructrl_obj_mgnt.host_obj[1].fructrl.get_ACCycleEnabled = function () return true end
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_chassis_ctrl({Cmd = 0x07}, {HostId = 1})
    end)
    assert(not ok, rsp)

    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_chassis_ctrl({Cmd = 0x08}, {HostId = 1})
    end)
    assert(not ok, rsp)
end

function TestIPMI:test_pp_ipmi_cmd_set_pwr_restore_policy()
    local cls = require 'pwr_powerctrl_ipmi'
    cls.fructrl_obj_mgnt.chassis_fructrl_ins = {
        set_PowerOnStrategy = function (...)
            return nil
        end
    }
     cls.fructrl_obj_mgnt.host_obj = {
        [1] = {
            fructrl = {
                set_PowerOnStrategy = function (...)
                    return nil
                end
            }
        }
     }
    cls:pp_ipmi_cmd_set_pwr_restore_policy({RestorePolicy = 0}, {HostId = 1})

    cls:pp_ipmi_cmd_set_pwr_restore_policy({RestorePolicy = 1}, {HostId = 1})

    cls:pp_ipmi_cmd_set_pwr_restore_policy({RestorePolicy = 2}, {HostId = 1})

    cls:pp_ipmi_cmd_set_pwr_restore_policy({RestorePolicy = 3}, {HostId = 1})

    local ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_set_pwr_restore_policy({RestorePolicy = 4}, {HostId = 1})
    end)
    assert(not ok, rsp)

end

function TestIPMI:test_ipmi_set_aclost_status()
    local cls = require 'pwr_powerctrl_ipmi'
    local ok, rsp
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    set_PwrStateBeforeACLost = function (...)return nil end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:ipmi_set_aclost_status({Status = 2}, {HostId = 1})
    end)
    assert(not ok, rsp)

    ok, rsp = pcall(function()
        cls:ipmi_set_aclost_status({Status = 1}, {HostId = 1})
    end)
    assert(not ok, rsp)
end

function TestIPMI:test_pp_ipmi_cmd_set_pwr_cycle_interval()
    local cls = require 'pwr_powerctrl_ipmi'
    local ok, rsp
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    set_PwrCycleDelaySeconds = function (...)return nil end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_set_pwr_cycle_interval({Seconds = 10}, {HostId = 1})
    end)
    assert(not ok, rsp)
end

function TestIPMI:test_pp_set_power_level()
    local cls = require 'pwr_powerctrl_ipmi'
    local ok, rsp
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    power_on_lock = {
                        is_power_locked_by_upgrade =  function() return false end
                    },
                    get_PwrOnLocked = function() return false end
                },
                powerapi = {
                        system_reset = function() end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:pp_set_power_level({PowerLevel = 0, LevelOption = 2}, {HostId = 1})
    end)
    assert(not ok, rsp)

    cls.fructrl_obj_mgnt.host_obj[1].powerapi.system_reset = function() return 1 end
    ok, rsp = pcall(function()
        cls:pp_set_power_level({PowerLevel = 0, LevelOption = 0}, {HostId = 1})
    end)
    assert(not ok, rsp)

    cls.fructrl_obj_mgnt.host_obj[1].powerapi.system_reset = function() return 0 end
    ok, rsp = pcall(function()
        cls:pp_set_power_level({PowerLevel = 0, LevelOption = 0}, {HostId = 1})
    end)
    assert(not ok, rsp)
end

function TestIPMI:test_pp_set_syslockdown_state()
    local cls = require 'pwr_powerctrl_ipmi'
    local ok, rsp
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                syslock = {
                    get_system_lockdown_support = function() return nil end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:pp_set_syslockdown_state({State = 2}, {HostId = 1})
    end)
    assert(not ok, rsp)
end

function TestIPMI:test_pp_ipmi_cmd_set_fru_activation()
    local cls = require 'pwr_powerctrl_ipmi'
    local ipmi_msg = {
        SetFruActivation ={
            rsp = {
                new = function() return nil end
            }
        }
    }
    assert(ipmi_msg)
    local ok, rsp
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    power_on_lock = {
                        is_power_locked_by_upgrade =  function() return false end
                    },
                    get_PwrOnLocked = function() return false end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_set_fru_activation({FruId = 0, Cmd = 1}, {HostId = 1})
    end)
    assert(not ok, rsp)
end

function TestIPMI:test_pp_ipmi_cmd_set_fru_activation_policy()
    local cls = require 'pwr_powerctrl_ipmi'
    local ipmi_msg = {
        SetFruActivationPolicy ={
            rsp = {
                new = function() return nil end
            }
        }
    }
    assert(ipmi_msg)
    local ok, rsp
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_set_fru_activation_policy({FruId = 0}, {HostId = 1})
    end)
    assert(not ok, rsp)
end

function TestIPMI:test_pp_ipmi_cmd_set_acpi_powerstate()
    local cls = require 'pwr_powerctrl_ipmi'
    local ipmi_msg = {
        SetACPIPowerState ={
            rsp = {
                new = function() return {ACPISystemPowerState = 0x00, CPIDevicePowerState = 0x00} end
            }
        }
    }

    local DEFALUTACPISTATE = ''
    local NOCHANGE = 'nochange'

    local SystemPowerState = {
        ['S0/G0'] = 0x00,
        ['S1'] = 0x01,
        ['S2'] = 0x02,
        ['S3'] = 0x03,
        ['S4'] = 0x04,
        ['S5/G2'] = 0x05,
        ['S4/S5'] = 0x06,
        ['G3'] = 0x07,
        ['sleeping'] = 0x08,
        ['G1 sleeping'] = 0x09,
        ['override'] = 0x0a,
        ['Legacy On'] = 0x20,
        ['Legacy Off'] = 0x21,
        ['unknown'] = 0x2a,
        [0x00] = 'S0/G0',
        [0x01] = 'S1',
        [0x02] = 'S2',
        [0x03] = 'S3',
        [0x04] = 'S4',
        [0x05] = 'S5/G2',
        [0x06] = 'S4/S5',
        [0x07] = 'G3',
        [0x08] = 'sleeping',
        [0x09] = 'G1 sleeping',
        [0x0a] = 'override',
        [0x20] = 'Legacy On',
        [0x21] = 'Legacy Off',
        [0x2a] = 'unknown',
        [0x7f] = NOCHANGE,
        [DEFALUTACPISTATE] = DEFALUTACPISTATE
    }

    local DevicePowerState = {
        [0x00] = 'D0',
        ['D0'] = 0x00,
        [0x01] = 'D1',
        ['D1'] = 0x01,
        [0x02] = 'D2',
        ['D2'] = 0x02,
        [0x03] = 'D3',
        ['D3'] = 0x03,
        [0x2a] = 'unknown',
        ['unknown'] = 0x2a,
        [0x7f] = NOCHANGE,
        [DEFALUTACPISTATE] = DEFALUTACPISTATE
    }
    assert(ipmi_msg)
    assert(SystemPowerState)
    assert(DevicePowerState)
    local ok, rsp
    cls.fructrl_obj_mgnt = {
        host_obj = {
            [1] = {
                fructrl = {
                    set_ACPISystemPowerState = function() return false end
                }
            }
        }
    }
    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_set_acpi_powerstate({ACPISystemPowerState = 0x83, ACPIDevicePowerState = 0x83}, {HostId = 1})
    end)
    assert(not ok, rsp)

    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_set_acpi_powerstate({ACPISystemPowerState = 0x80, ACPIDevicePowerState = 0x80}, {HostId = 1})
    end)
    assert(not ok, rsp)

    ok, rsp = pcall(function()
        cls:pp_ipmi_cmd_set_acpi_powerstate({ACPISystemPowerState = 0x7F, ACPIDevicePowerState = 0x83}, {HostId = 1})
    end)
    assert(not ok, rsp)
end
