-- Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. 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 client = require 'thermal_mgmt.client'
local enums = require 'basic_cooling.define.cooling_enums'
local props = require 'basic_cooling.define.cooling_properties'
local base = require 'basic_cooling.data_keeping.base'
local singleton = require 'mc.singleton'

local hddbackplane_data_keeping = class(base)

function hddbackplane_data_keeping:ctor(bus)
    self.obj_name = "HDDBackPlane"
    -- 监听的资源树路径
    self.paths_table = {
        "/bmc/kepler/Systems/:SystemId/Boards/HddBackplane/:Id"
    }
    -- 监听的接口
    self.interfaces_table = {
        ["bmc.kepler.Systems.Board"] = {
            [enums.data_keeping_config.FOREACH_FUNC] = client.ForeachBoardObjects,
            [enums.data_keeping_config.PROPERTIES] = {
                [props.HDD_BACK_PLANE.NAME] = enums.data_keeping_log.LOG
            }
        }
    }

    self.loaded_hdd_backplanes = {}
    self.hdd_backplane_path_name_map = {}
end

function hddbackplane_data_keeping:init()
    self.super.init(self)
end

function hddbackplane_data_keeping:action_after_obj_added(path, interface)
    if self.hdd_backplane_path_name_map[path] then
        log:error("Duplicated hdd backplane obj(path:%s)", path)
        return
    end
    local name = self.objs[path][interface][props.HDD_BACK_PLANE.NAME]
    self.hdd_backplane_path_name_map[path] = name

    self.loaded_hdd_backplanes[name] = (not self.loaded_hdd_backplanes[name]) and
        1 or (self.loaded_hdd_backplanes[name] + 1)

    log:notice("Add hdd backplane obj(path:%s), name: %s, cur number:%u",
        path, name, self.loaded_hdd_backplanes[name])
end

function hddbackplane_data_keeping:action_after_obj_removed(path, interface)
    if not self.hdd_backplane_path_name_map[path] then
        log:error("Hdd backplane obj(path:%s) not in table", path)
        return
    end

    local name = self.objs[path][interface][props.HDD_BACK_PLANE.NAME]
    self.hdd_backplane_path_name_map[path] = nil

    if self.loaded_hdd_backplanes[name] >= 1 then
        self.loaded_hdd_backplanes[name] = self.loaded_hdd_backplanes[name] - 1
    else
        log:error("The number of hdd backplane obj(name:%s) less then 1", name)
    end

    log:notice("Delete hdd backplane obj(path:%s), cur number:%u", path,
        self.loaded_hdd_backplanes[name])
end

function hddbackplane_data_keeping:action_after_property_changed(path, interface, prop, value)
    if prop ~= props.HDD_BACK_PLANE.NAME then
        return
    end
    local pre_hdd_backplane_name = self.hdd_backplane_path_name_map[path]
    if self.loaded_hdd_backplanes[pre_hdd_backplane_name] >= 1 then
        self.loaded_hdd_backplanes[pre_hdd_backplane_name] = self.loaded_hdd_backplanes[pre_hdd_backplane_name] - 1
        log:notice('Update the number of hdd backplane obj(name:%s), cur number: %s', pre_hdd_backplane_name,
            self.loaded_hdd_backplanes[pre_hdd_backplane_name])
    else
        log:error("The number of hdd backplane obj(name:%s) less then 1", pre_hdd_backplane_name)
    end

    self.loaded_hdd_backplanes[value] = (not self.loaded_hdd_backplanes[value]) and
        1 or (self.loaded_hdd_backplanes[value] + 1)
    self.hdd_backplane_path_name_map[path] = value

    log:notice("Update hdd backplane obj(path:%s), pre name: %s, name: %s, cur number:%s",
        path, pre_hdd_backplane_name, value, self.loaded_hdd_backplanes[value])
end

function hddbackplane_data_keeping:is_hdd_backplane_loaded(name)
    return self.loaded_hdd_backplanes[name] and self.loaded_hdd_backplanes[name] > 0
end

return singleton(hddbackplane_data_keeping)