-- 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 skynet = require 'skynet'
local log = require 'mc.logging'
local Singleton = require 'mc.singleton'
local cooling_device_base = require 'basic_cooling.cooling_device.base'
local props = require 'basic_cooling.define.cooling_properties'

local cooling_pumps = class(cooling_device_base)

local PUMP_OBJ_ADD_TIMEOUT_TIMES <const> = 30 -- 泵对象添加超时次数，累计时间为600s
function cooling_pumps:init()
    self.super.init(self)
    self.syn_id = 'Id'
    self.interface = 'bmc.kepler.Systems.CoolingPump'
    self.class_name = 'CoolingPump'
    self.pwm_name = 'ActualPWM'

    self.pump_add_complete_num = 0 --散热泵分发完成个数
    self.pump_num = nil -- 当前机型参与调速的散热泵个数

    skynet.fork_once(function()
        for i = 1, PUMP_OBJ_ADD_TIMEOUT_TIMES, 1 do
            -- 如果泵对象添加完成直接退出
            if self.obj_add_complete_flag then
                log:notice('Pump object timeout detection exit')
                break
            end
            skynet.sleep(2000)
        end
        local pump_id_string = ''
        for _, pump_obj in pairs(self.obj_table) do
            pump_id_string = pump_id_string .. ' ' .. pump_obj[self.syn_id]
        end
        if self.obj_add_complete_flag == false then
            -- 达到超时时间且泵板分发缺失时，强制进行一次检测以启动cooling调速服务
            log:notice('Pump object timeout detection starting, expect pumps num: %s, cur pumps num: %s',
                self.pump_add_complete_num, self.pump_num
            )
            log:notice('%s object id identify result: %s', self.class_name, pump_id_string)
            if self.pump_num and self.pump_add_complete_num < self.pump_num and self.pump_add_complete_num ~= 0 then
                self:update_cooling_device_obj_identify_result()
            end
        end
    end)
end

function cooling_pumps:obj_add_callback(class_name, object, position)
    self.super.obj_add_callback(self,class_name,object,position)
    self:update_cooling_obj(object)
end

function cooling_device_base:update_cooling_obj(object)
    if self.obj_table[object[props.OBJECT_NAME]] then
        self.pump_add_complete_num = self.pump_add_complete_num + 1
        log:notice('Receive object complete, cur num: %s',
            self.pump_add_complete_num)
    end
end

function cooling_device_base:update_cooling_objs_recived_status(max_pump_num, position)
    -- MaxPumpNum挂在psr的LiquidCoolingConfig上，此处传入的可能为nil
    self.pump_num = max_pump_num and max_pump_num or self.pump_num
    log:notice('Receive obj complete, cur num: %s, self.board_num: %s',
        self.pump_add_complete_num, self.pump_num)
    -- 当所有泵板都分发完成后，进行初次CoolingPump进行分发缓存
    -- 泵板卸载重加载场景会收到重复的泵板sr添加完成信号
    if self.pump_num and self.pump_add_complete_num >= self.pump_num then
        self:update_cooling_device_obj_identify_result()
    end
end

function cooling_pumps:props_changed_callback(object, name, value, sender)
    if name == self.syn_id then
        -- 所有泵都添加分发完成CoolingPump的Id又更新后，对CoolingPump进行分发缓存
        if self.pump_num and self.pump_add_complete_num >= self.pump_num then
            self:update_cooling_device_obj_identify_result()
        end
    end
end

return Singleton(cooling_pumps)