-- 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 class = require 'mc.class'
local singleton = require 'mc.singleton'
local log = require 'mc.logging'
local mdb = require 'mc.mdb'
local c_fan_object = require 'fan_object'

local FAN_FRPM <const> = 'fan.frpm'
local FAN_RRPM <const> = 'fan.rrpm'

local metric_collect = class()

function metric_collect:ctor(bus)
    self.bus = bus
end

local function find_fan_object(interface_obj)
    local fan_obj_map = {}
    -- 填充map
    c_fan_object.collection:fold(function (_, obj)
        fan_obj_map[obj['bmc.kepler.Metric']] = obj
    end)
    return fan_obj_map[interface_obj]
end

function metric_collect:get_fan_data_collection_items(obj)
    -- 对象不在位或初始化未完成时无需触发采集
    local fan_obj = find_fan_object(obj)
    if not fan_obj or (fan_obj.FrontPresence ~= 1 and fan_obj.RearPresence ~= 1) or (fan_obj.Model == '') then
        return '', {}, {}, {}
    end

    local Classification = {
        { PropName = 'Model', PropVal = fan_obj.Model },
        { PropName = 'Fspeed', PropVal = tostring(fan_obj.FrontMaxSpeed) },
        { PropName = 'Rspeed', PropVal = tostring(fan_obj.RearMaxSpeed) },
        { PropName = 'SystemId', PropVal = '1' }
    }
    local Identification = {
        { PropName = 'FANSlot', PropVal = tostring(fan_obj.Slot) },
        { PropName = 'ComNodeId', PropVal = tostring(fan_obj.FanId - 1) }
    }
    local MetricName = {
        FAN_FRPM, FAN_RRPM
    }
    return 'Fan', Classification, Identification, MetricName
end

local function get_frontrpm(data, object)
    table.insert(data, tostring(object.FrontSpeed))
end

local function get_rearrpm(data, object)
    table.insert(data, tostring(object.RearSpeed))
end

local metric_func_table = {
    [FAN_FRPM] = { metric_func = get_frontrpm },
    [FAN_RRPM] = { metric_func = get_rearrpm }
}

local function get_metric_data(object, metric_name)
    log:debug('metric_name = %s', metric_name)
    local data = {}
    if metric_func_table[metric_name] ~= nil then
        metric_func_table[metric_name].metric_func(data, object)
    else
        log:info('invalid metric, metric_name = %s', metric_name)
    end
    return data
end

function metric_collect:get_fan_data_collection_data(obj, metric_name)
    local fan_obj = find_fan_object(obj)
    if not fan_obj then
        return {}
    end
    local Val = {}
    for _, value in ipairs(metric_name) do
        local data = get_metric_data(fan_obj, value)
        if #data ~= 0 then
            table.insert(Val, { MetricName = value, Data = data })
        end
    end
    return Val
end

return singleton(metric_collect)