-- 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: Trap信息管理
-- SMTP TRAP团体名最大长度
local SMTP_TRAP_COMMUNITY_MAX_LEN = 32
-- 复杂度检查禁能时的SMTP TRAP团体名最小长度
local SMTP_TRAP_COMMUNITY_MIN_LEN = 1

local m = {}

local function band(data, mask)
    if data == nil or mask == nil then
        return
    end

    if type(data) ~= "number" or type(mask) ~= "number" then
        return
    end

    return data & mask
end

function m.get_severity(severity_filter)
    if severity_filter == 0 then
        return 'none'
    elseif severity_filter == 15 then
        return 'all'
    end

    local severity = {}

    if band(severity_filter, 0x01) == 1 then
        severity[#severity + 1] = 'normal'
    end

    if band(severity_filter, 0x02) == 2 then
        severity[#severity + 1] = 'minor'
    end

    if band(severity_filter, 0x04) == 4 then
        severity[#severity + 1] = 'major'
    end

    if band(severity_filter, 0x08) == 8 then
        severity[#severity + 1] = 'critical'
    end

    return table.concat(severity, '  ')
end

local severity_mask = {
    normal = 0x1,
    minor = 0x2,
    major = 0x4,
    critical = 0x8
}

function m.check_severity(ReqBody)
    local severity = {}
    for _, value in pairs(ReqBody) do
        if value ~= nil then
            severity[#severity + 1] = value
        end
    end

    if #severity == 1 then
        local all_severity_mask = severity_mask
        all_severity_mask['none'] = 0
        all_severity_mask['all'] = 15
        for _, value in ipairs(severity) do
            if all_severity_mask[value] == nil then
                return false
            end
        end
    else
        local severity_count = {
            normal = 0,
            minor = 0,
            major = 0,
            critical = 0
        }
        for _, value in ipairs(severity) do
            if severity_count[value] == nil then
                return false
            end

            if severity_count[value] ~= 0 then
                return false
            end

            severity_count[value] = severity_count[value] + 1
        end
    end

    return true
end

function m.get_severity_filter(ReqBody)
    local severity = {}
    for _, value in pairs(ReqBody) do
        if value ~= nil then
            severity[#severity + 1] = value
        end
    end

    local severity_filter = 0
    if #severity == 1 then
        local all_severity_mask = severity_mask
        all_severity_mask['none'] = 0
        all_severity_mask['all'] = 15
        for _, value in ipairs(severity) do
            severity_filter = all_severity_mask[value]
        end
    else
        for _, value in ipairs(severity) do
            if severity_mask[value] then
                severity_filter = severity_filter | severity_mask[value]
            end
        end
    end

    return severity_filter
end

function m.get_community()
    local status, new_community, confirm_community
    status, new_community = libroutemapper_utils.get_line_without_echo('New Community:')
    if status ~= 0 or #new_community < SMTP_TRAP_COMMUNITY_MIN_LEN or #new_community > SMTP_TRAP_COMMUNITY_MAX_LEN then
        return {
            ok = false,
            ret = string.format('Community length must be between %d to %d.', SMTP_TRAP_COMMUNITY_MIN_LEN,
                SMTP_TRAP_COMMUNITY_MAX_LEN)
        }
    end

    status, confirm_community = libroutemapper_utils.get_line_without_echo('Confirm Community:')
    if status ~= 0 or confirm_community ~= new_community then
        return { ok = false, ret = 'Confirm community error.' }
    end

    return { ok = true, ret = new_community }
end

return m
