-- 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 device_object = require 'mc.mdb.device_tree.device_object'
local log = require 'mc.logging'

local fan = device_object('Fan')

local RET_ERR<const> = 1
local RET_OK<const>  = 0

local identify_status<const> = {
    UNIDENTIFIED = 0,
    IDENTIFYING = 1,
    IDENTIFIED = 2,
    IDENTIFY_FAILED = 3
}

function fan:ctor()
end

function fan:configurable()
    -- 仅支持对已识别或者不在位的风扇进行调速
    return self:is_identified() or not (self:get_present() == 1)
end

function fan:set_fan_expected_pwm(pwm)
    self.ExpectedPWM = math.floor(pwm + 0.5)
end

function fan:is_identified()
    return self.IdentifyStatus == identify_status.IDENTIFIED
end

function fan:get_present()
    return self.RearPresence
end

--- @description 设置风扇转速（无校验）
--- @param pwm_percent number 
function fan:set_fan_hardware_pwm(pwm_percent)
    local pwm_value = pwm_percent / 100 * self.MaxSupportedPWM
    -- 设置pwm，四舍五入
    self.HardwarePWM = math.floor(pwm_value + 0.5)
    self.ExpectedPWM = math.floor(pwm_value + 0.5)
    log:debug("pwm_percent(%s) set pwm_value: %s, HardwarePWM: %s", pwm_percent, pwm_value, self.HardwarePWM)
end

--- @description 设置风扇转速（有校验）
--- @param pwm_value number
--- @return 0|1 
function fan:set_fan_pwm(pwm_value)
    if not self:configurable() then
        return RET_ERR
    end
    local ok, ret = pcall(function ()
        self:set_fan_hardware_pwm(pwm_value)
    end)
    if not ok then
        log:info("set pwm_value(%s) failed. ret: %s", pwm_value, ret)
        return RET_ERR
    end
    return RET_OK
end

function fan:init()
    -- 设置期望转速（批量调速后调用）
    self:declare_method('Fan', 'bmc.dev.Fan', 'SetFanExpectedPWM', function (...)
        self:set_fan_expected_pwm(...)
    end)
    -- 设置风扇转速（有校验）
    self:declare_method('Fan', 'bmc.dev.Fan', 'SetFanPWM', function (...)
        return self:set_fan_pwm(...)
    end)
    -- 设置风扇转速（无校验）
    self:declare_method('Fan', 'bmc.dev.Fan', 'SetFanHardwarePWM', function (...)
        self:set_fan_hardware_pwm(...)
    end)
    -- 风扇当前是否支持调速
    self:declare_method('Fan', 'bmc.dev.Fan', 'Configurable', function ()
        return self:configurable()
    end)
end

return fan