-- Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
-- 
-- this file licensed under the 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 class = require 'mc.class'
local log = require 'mc.logging'
local cooling_enums = require 'basic_cooling.define.cooling_enums'
local utils = require 'basic_cooling.cooling_utils'
local props = require 'basic_cooling.define.cooling_properties'
local Singleton = require 'mc.singleton'
local cooling_config_base = require 'basic_cooling.cooling_config.base'
local context = require 'mc.context'

local air_config = class(cooling_config_base)

function air_config:ctor()
    self.obj = nil
    self.cooling_config_obj = nil
    self.manual_mode_status_table = {
        last_timeout = nil, -- 上次更新的timeout
        real_timeout = nil, -- 用于业务逻辑计算的超时时间
        expir_time = nil,   -- timeout结束的时间
        pre_manual_level_tab = nil
    }
    self.object_from_sr = true
end

function air_config:set_cooling_config_obj(object)
    self.cooling_config_obj = object
end

function air_config:set_obj(object)
    self.obj = object
    object:get_mdb_object('bmc.kepler.Systems.AirCoolingConfig').property_changed:on(function(name, value, sender)
        self:props_changed_callback(object, name, value, sender)
    end)
end

function air_config:is_obj_added()
    if self.obj then
        return true
    end
    return false
end

function air_config:props_changed_callback(object, name, value, sender)
    if name == props.INITIAL_SPEED_PERCENT then
        if self.cooling_config_obj then
            self.cooling_config_obj[props.INIT_LEVEL_IN_STARTUP] = value
        end
    elseif name == "MinAllowedSpeedPercent" then
        if self.cooling_config_obj then
            self.cooling_config_obj.MinAllowedFanSpeedPercent = value
        end
    elseif name == props.FAN_SPEED_DEVIATION_THRESHOLD_PERCENT then
        local ctx = context.get_context()
        utils.op(ctx, "Set SpeedDeviationThresholdPercent allowed speed percent to %s", value)
    end
end

function air_config:set_min_allowed_speed_percent(value)
    if not self.obj then
        return
    end
    local ctx = context.get_context()
    utils.op(ctx, "Set min fan allowed speed percent to %s", value)
    self.obj.MinAllowedSpeedPercent = value
end

function air_config:set_init_level_in_startup(value)
    if not self.obj then
        return
    end
    self.obj[props.INITIAL_SPEED_PERCENT] = value
end

function air_config:get_init_level_in_startup()
    if not self.obj then
        return nil
    end
    return self.obj[props.INITIAL_SPEED_PERCENT]
end

-- 设置手动转速
function air_config:set_manual_level(value)
    if not self.obj then
        return
    end
    self.obj[props.MANUAL_SPEED_PERCENT] = value
end

-- 设置持久化的手动转速
function air_config:set_manual_level_persist(value)
    if not self.obj then
        return
    end
    if self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.ResetPer then
        self.obj[props.MANUAL_SPEED_PERCENT_RESET_PERSIST] = value
    elseif self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.PoweroffPer then
        self.obj[props.MANUAL_SPEED_PERCENT_POWEROFF_PERSIST] = value
    end
end

-- 获取手动转速
function air_config:get_manual_level()
    if not self.obj then
        return nil
    end
    return self.obj[props.MANUAL_SPEED_PERCENT]
end

-- 获取转速区间
function air_config:get_level_range()
    if not self.obj then
        return nil
    end
    return self.obj[props.SPEED_PERCENT_RANGE]
end

-- 设置可持久化的控制模式
function air_config:set_ctrl_mode_persist(value)
    if not self.obj then
        return false
    end
    log:notice("Current manual speed percent is %s, control mode persist type is %s",
        value, self.obj[props.CTRL_MODE_PERSIST_TYPE])
    if self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.ResetPer then
        self.obj[props.CTL_MODE_RESET_PERSIST] = value
    elseif self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.PoweroffPer then
        self.obj[props.CTL_MODE_POWEROFF_PERSIST] = value
    end
    return true
end

-- 获取可持久化的控制模式
function air_config:get_ctrl_mode_persist()
    if not self.obj then
        return nil
    end
    if self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.Memory then
        return self.obj[props.CTL_MODE]
    elseif self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.ResetPer then
        return self.obj[props.CTL_MODE_RESET_PERSIST]
    elseif self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.PoweroffPer then
        return self.obj[props.CTL_MODE_POWEROFF_PERSIST]
    end
end

-- 设置风扇控制模式持久化类型
function air_config:set_ctrl_mode_persist_type(value)
    if not self.obj then
        return false
    end
    self.obj[props.CTRL_MODE_PERSIST_TYPE] = value
    return true
end

-- 获取风扇控制模式持久化类型
function air_config:get_ctrl_mode_persist_type()
    if not self.obj then
        return nil
    end
    return self.obj[props.CTRL_MODE_PERSIST_TYPE]
end

-- 获取可持久化的手动转速
function air_config:get_manual_speed_percent_persist()
    if not self.obj then
        return nil
    end
    if self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.Memory then
        return self.obj[props.MANUAL_SPEED_PERCENT]
    elseif self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.ResetPer then
        return self.obj[props.MANUAL_SPEED_PERCENT_RESET_PERSIST]
    elseif self.obj[props.CTRL_MODE_PERSIST_TYPE] == cooling_enums.persist_type.PoweroffPer then
        return self.obj[props.MANUAL_SPEED_PERCENT_POWEROFF_PERSIST]
    end
end

function air_config:set_active_algorithm(value)
    if not self.obj then
        return
    end
    if self.obj[props.ACTIVE_ALGORITHM] ~= value then
        self.obj[props.ACTIVE_ALGORITHM] = value
    end
end

function air_config:get_deviation_threshold_percent()
    if not self.obj then
        return 25 --风扇转速偏移阈值默认值
    end
    return self.obj[props.FAN_SPEED_DEVIATION_THRESHOLD_PERCENT]
end

function air_config:get_active_algorithm()
    if not self.obj then
        return nil
    end
    return self.obj[props.ACTIVE_ALGORITHM]
end

function air_config:get_fan_ctrl_mode()
    if not self.obj then
        return nil
    end
    return self.obj[props.CTL_MODE]
end

return Singleton(air_config)