-- 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 ipmimsg = require 'manufacture.ipmi.cmds.ClearCmos'
local ipmi = require 'ipmi'
local log = require 'mc.logging'
local factory = require 'factory'
local skynet = require 'skynet'
local bs = require 'mc.bitstring'

local cc = ipmi.types.Cc

local ipmi_handler = {}
local FAIL_LOG<const> = "Set cmos clear flag failed"
local SUCCESS_LOG<const> = "Set cmos clear flag successfully"
local RECOVER_STATUS_IN_PROCESS<const> = 0x00
local RECOVER_STATUS_COMPLETED<const> = 0x01
local RECOVER_STATUS_FAIL<const> = 0x02

local function check_manufacture(manufacture)
    if manufacture ~= 0x0007db then
        log:error("check manufactureId failed")
        return false
    end
    return true
end

local function check_dft_mode()
    local manufacture_service = factory.get_obj("manufacture_service")
    local dft_mode = manufacture_service:get_dft_mode()
    if not dft_mode or dft_mode ~= 0 then
        return false
    end
    return true
end

local function response(code, req, status)
    return ipmimsg.ClearCmosRsp.new(code, req.ManufactureId, status)
end


local function clear_cmos()
    local manufacture_service = factory.get_obj("manufacture_service")
    return manufacture_service:clear_cmos()
end

function ipmi_handler.clear_cmos(req, ctx)
    log:debug("clear cmos")
    local action = req.Action
    if not check_manufacture(req.ManufactureId) then
        return response(cc.InvalidFieldRequest, req, 0)
    end
    if not check_dft_mode() then
        log:error("cmd only for dft mode")
        ipmi.ipmi_operation_log(ctx, 'manufacture', FAIL_LOG)
        return response(cc.Success, req, RECOVER_STATUS_FAIL)
    end
    if not clear_cmos() then
        ipmi.ipmi_operation_log(ctx, 'manufacture', FAIL_LOG)
        return response(cc.Success, req, RECOVER_STATUS_FAIL)
    end
    ipmi.ipmi_operation_log(ctx, 'manufacture', SUCCESS_LOG)
    skynet.fork(function ()
        skynet.sleep(200) -- 等两秒钟再执行重启动作
        local action_req = bs.new("<<reboot_flag:1, resd:7>>")
        local param = action_req:unpack(action)
        if param.reboot_flag == 1 then
            local manufacture_service = factory.get_obj("manufacture_service")
            manufacture_service:reboot()
        end
    end)
    return response(cc.Success, req, RECOVER_STATUS_COMPLETED)
end

return ipmi_handler