-- 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.
--         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 cmn = require 'common'
local log = require 'mc.logging'
local RETIMER_CONSTANTS = require 'retimer.retimer_constants'
local context = require 'mc.context'
local intf_client = require 'general_hardware.client'
local agent = require 'retimer.agent'
local mdb = require 'mc.mdb'

local retimer = {}
retimer.__index = retimer

function retimer.new(object, bus)
    local obj = setmetatable({retimer_obj = object}, retimer)
    obj.name = object.name
    obj.bus = bus
    obj.upgrade_status = RETIMER_CONSTANTS.UPGRADE_STATUS.IDLE
    -- 创建代理，启动代理任务，定时刷新属性
    obj.agent = agent.new(obj.retimer_obj.ChipType, obj, bus)
    if obj.agent then
        obj.agent:start()
    end
    return obj
end

function retimer:cleanup()
    if self.agent then
        self.agent:stop()
    end
end

function retimer:get_upgrade_status()
    return self.upgrade_status
end

function retimer:get_chip_type()
    return self.retimer_obj.ChipType
end

function retimer:get_chip_temp()
    return self.retimer_obj.TemperatureCelsius
end

--- @function 向FirmwareInventory注册
function retimer:register_firmware_info()
    cmn.skynet.fork(function()
        log:notice('[Retimer] register retimer version to firmware inventory')

        local param = {
            Id = self.retimer_obj.ChipName,
            Name = self.retimer_obj.ChipName,
            Version = '',
            BuildNum = '',
            ReleaseDate = '',
            LowestSupportedVersion = '',
            SoftwareId = 'Retimer-M88RT51632',
            Manufacturer = 'Huawei',
            Location = self.retimer_obj.ChipLocation,
            State = 'Enabled',
            Severity = 'Informational'
        }
        local retries = 0
        local ok
        repeat
            ok, _ = intf_client:PFirmwareInventoryFirmwareInventoryAdd(context.new(),
                param, true, 1, 10) -- retimer固件包大小暂时不知，先预留10MB
            if not ok then
                retries = retries + 1
                cmn.skynet.sleep(100)
            end
        until ok or retries > 120  -- 最多重试2分钟
    end)
end

--- @function 更新FirmwareInventory的Version属性
function retimer:update_firmware_version()
    local path = '/bmc/kepler/UpdateService/FirmwareInventory/' .. self.retimer_obj.ChipName
    local ok, obj = pcall(mdb.get_cached_object, self.bus, path, 'bmc.kepler.UpdateService.FirmwareInfo')
    if not ok then
        log:error('get firmware object failed, path: %s, obj: %s',
            path, obj)
        return
    end
    local version = self.retimer_obj.FirmwareVersion
    if version ~= obj.Version then
        obj.Version = version
        log:notice('update retimer firmware version %s to FirmwareInventory, id: %s', obj.Version, self.name)
    end
end

--- @function 更新FirmwareInventory的Severity属性
function retimer:update_firmware_severity()
    local path = '/bmc/kepler/UpdateService/FirmwareInventory/' .. self.retimer_obj.ChipName
    local ok, obj = pcall(mdb.get_cached_object, self.bus, path, 'bmc.kepler.UpdateService.FirmwareInfo')
    if not ok then
        log:error('get firmware object failed, path: %s, obj: %s',
            path, obj)
        return
    end
    obj.Severity = self.retimer_obj.HealthStatus == 0 and "Informational" or "Major"
end

return retimer
