-- 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.

-- Description: Centralized operation log management for sensor module.
local ipmi = require 'ipmi'
local log = require 'mc.logging'

local operation = {}
operation.__index = operation

-- 操作结果
operation.SUCCESS = 1
operation.FAILED  = 2

-- 操作日志索引集合
operation.GLOBAL_ENABLES = 101
operation.PEF_LAST_EVENT = 201
operation.PEF_POSTPONE   = 202
operation.PEF_PROGRESS   = 203
operation.PEF_CONTROL    = 204
operation.PEF_ACTION     = 205
operation.PEF_STARTUP    = 206
operation.PEF_AL_STARTUP = 207
operation.PEF_AL_TABLE   = 208
operation.PEF_AL_DATA    = 209
operation.PEF_PLCY_TABLE = 210
operation.PEF_GUID       = 211
operation.PEF_AL_KEYS    = 212
operation.PEF_AL_STRING  = 213
operation.PEF_ENABLE     = 214
operation.PEF_CONF       = 299
operation.SDR_UPDATE_EX  = 301
operation.SDR_UPDATE_EN  = 302
operation.SDR_CLEAR      = 303
operation.SDR_ADD        = 304
operation.SDR_ADD_DATA   = 305
operation.SEL_RECVER     = 401
operation.SEL_CLEAR      = 402
operation.SEL_ADD        = 403
operation.SEL_MAXNUM     = 404
operation.SEL_MODE       = 405
operation.SEL_COLLECTED  = 406
operation.SEL_EXPORT     = 407
operation.SEL_REPORT     = 408
operation.SENSOR_HYSTER  = 501
operation.SENSOR_THRES   = 502
operation.SENSOR_ENABLE  = 503
operation.SENSOR_NUMBASE = 504
operation.BASE_OS_BOOT_EVENT = 601

-- 操作日志集合，其中 1 是成功的，2 是失败的
local log_map = {
    [operation.GLOBAL_ENABLES] = {
        'Set global enables to (RAW:%02x) successfully',
        'Set global enables failed'
    },
    [operation.PEF_LAST_EVENT] = {
        'Set Last Event Id by IPMI successfully',
        'Set Last Event Id by IPMI failed'
    },
    [operation.PEF_POSTPONE] = {
        'Arm PEF postpone timer successfully'
    },
    [operation.PEF_PROGRESS] = {
        'Set pef progress status to (RAW:%02X-%02X) successfully'
    },
    [operation.PEF_CONTROL] = {
        'Set PEF control to (RAW:%02X-%02X) successfully'
    },
    [operation.PEF_ACTION] = {
        'Set PEF action global control to (RAW:%02X-%02X) successfully'
    },
    [operation.PEF_STARTUP] = {
        'Set PEF startup delay to (RAW:%02X-%02X) successfully'
    },
    [operation.PEF_AL_STARTUP] = {
        'Set PEF alert startup delay to (RAW:%02X-%02X) successfully'
    },
    [operation.PEF_AL_TABLE] = {
        'Set event filter table to (RAW:%s) successfully'
    },
    [operation.PEF_AL_DATA] = {
        'Set event filter table data1 to (RAW:%02X-%02X-%02X) successfully'
    },
    [operation.PEF_PLCY_TABLE] = {
        'Set alert policy table to (RAW:%s) successfully'
    },
    [operation.PEF_GUID] = {
        'Set PEF system guid to (RAW:%s) successfully'
    },
    [operation.PEF_AL_KEYS] = {
        'Set alert string keys to (RAW:%s) successfully'
    },
    [operation.PEF_AL_STRING] = {
        'Set alert string to (RAW:%s) successfully'
    },
    [operation.PEF_ENABLE] = {
        'Set pef configuration enable to (%s) successfully',
        'Set pef configuration enable failed'
    },
    [operation.PEF_CONF] = {
        '',
        'Set pef conf parameters by IPMI failed'
    },
    [operation.SDR_UPDATE_EX] = {
        'Exit SDR repository update mode successfully',
        'Exit SDR repository update mode failed'
    },
    [operation.SDR_UPDATE_EN] = {
        'Enter SDR repository update mode successfully',
        'Enter SDR repository update mode failed'
    },
    [operation.SDR_CLEAR] = {
        'Clear SDR repository successfully',
        'Clear SDR repository failed'
    },
    [operation.SDR_ADD] = {
        'Partial add SDR record (%d) successfully',
        'Partial add SDR record failed'
    },
    [operation.SDR_ADD_DATA] = {
        'Add SDR record (%d) successfully',
        'Add SDR record failed'
    },
    [operation.SEL_RECVER] = {
        'Set event receiver successfully',
        'Set event receiver failed'
    },
    [operation.SEL_CLEAR] = {
        'Clear SEL records successfully',
        'Clear SEL records failed due to %s'
    },
    [operation.SEL_ADD] = {
        'Add SEL entry successfully',
        'Add SEL entry failed'
    },
    [operation.SEL_MAXNUM] = {
        'Set query SEL max number over IPMI to (%d) successfully',
        'Set query SEL max number over IPMI failed'
    },
    [operation.SEL_MODE] = {
        'Set SEL mode to (%s) successfully',
        'Set SEL mode failed'
    },
    [operation.SEL_COLLECTED] = {
        'Collect sensor event log successfully'
    },
    [operation.SEL_EXPORT] = {
        'Export sensor event log to local successfully',
        'Export sensor event log failed'
    },
    [operation.SEL_REPORT] = {
        'Report sensor event successfully',
        'Report sensor event failed'
    },
    [operation.SENSOR_HYSTER] = {
        'Set sensor(%s) negative hysteresis to (%.2f) positive hysteresis to (%.2f) successfully',
        'Set sensor hysteresis by IPMI failed'
    },
    [operation.SENSOR_THRES] = {
        'Set sensor(%s) %s threshold to (%.2f) successfully',
        'Set sensor threshold by IPMI failed'
    },
    [operation.SENSOR_ENABLE] = {
        'Set sensor(%s) event enable to (RAW:%s) successfully',
        'Set sensor event enable failed'
    },
    [operation.SENSOR_NUMBASE] = {
        'Set sdr dynamic sensor number base to (%d) successfully',
        'Set sdr dynamic sensor number base failed'
    },
    [operation.BASE_OS_BOOT_EVENT] = {
        'Set OS Boot data to 0x%08X successfully'
    },
}

function operation.log(ctx, key, ret, ...)
    if not log_map[key] or not log_map[key][ret] then
        log:error('operation log key [%d] or ret [%d] is invalid.', key, ret)
        return
    end

    local ok, caller = pcall(function() return ctx:get_initiator() end)
    if ok and caller and caller.Interface ~= 'IPMI' then
        -- 说明是 method operation log
        return log:operation(caller, 'sensor', log_map[key][ret], ...)
    end
    return ipmi.ipmi_operation_log(ctx, 'sensor', log_map[key][ret], ...)
end

return operation