-- Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. 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 role = require 'domain.cache.role_cache'
-- Privilege类用于session等对象在内存中临时持有，用于快速判断用户是否有权限操作相关接口，不用于角色管理，支持多角色
local Privilege = class()

---@param UserMgmt boolean
---@param BasicSetting boolean
---@param KVMMgmt boolean
---@param ReadOnly boolean
---@param VMMMgmt boolean
---@param SecurityMgmt boolean
---@param PowerMgmt boolean
---@param DiagnoseMgmt boolean
---@param ConfigureSelf boolean
function Privilege:ctor(UserMgmt, BasicSetting, KVMMgmt, ReadOnly, VMMMgmt, SecurityMgmt, PowerMgmt,
                       DiagnoseMgmt, ConfigureSelf)
    self.m_UserMgmt = UserMgmt
    self.m_BasicSetting = BasicSetting
    self.m_KVMMgmt = KVMMgmt
    self.m_ReadOnly = ReadOnly
    self.m_VMMMgmt = VMMMgmt
    self.m_SecurityMgmt = SecurityMgmt
    self.m_PowerMgmt = PowerMgmt
    self.m_DiagnoseMgmt = DiagnoseMgmt
    self.m_ConfigureSelf = ConfigureSelf
end

function Privilege.new_from_data(data)
    return setmetatable({
        m_UserMgmt = data.UserMgmt,
        m_BasicSetting = data.BasicSetting,
        m_KVMMgmt = data.KVMMgmt,
        m_ReadOnly = data.ReadOnly,
        m_VMMMgmt = data.VMMMgmt,
        m_SecurityMgmt = data.SecurityMgmt,
        m_PowerMgmt = data.PowerMgmt,
        m_DiagnoseMgmt = data.DiagnoseMgmt,
        m_ConfigureSelf = data.ConfigureSelf
    }, Privilege)
end

-- 重载 '+' 运算符
function Privilege.__add(a, b)
    return Privilege.new(a.m_UserMgmt or b.m_UserMgmt, a.m_BasicSetting or b.m_BasicSetting,
        a.m_KVMMgmt or b.m_KVMMgmt, a.m_ReadOnly or b.m_ReadOnly, a.m_VMMMgmt or b.m_VMMMgmt,
        a.m_SecurityMgmt or b.m_SecurityMgmt, a.m_PowerMgmt or b.m_PowerMgmt,
        a.m_DiagnoseMgmt or b.m_DiagnoseMgmt, a.m_ConfigureSelf or b.m_ConfigureSelf)
end

local function parse_priv_data(privileges)
    local res = {
        ReadOnly      = false,
        DiagnoseMgmt  = false,
        SecurityMgmt  = false,
        BasicSetting  = false,
        UserMgmt      = false,
        PowerMgmt     = false,
        VMMMgmt       = false,
        KVMMgmt       = false,
        ConfigureSelf = false
    }
    for _, v in pairs(privileges) do
        res[v] = true
    end

    return res
end

function Privilege.new_from_role_ids(role_ids)
    local res = Privilege.new(false, false, false, false, false, false, false, false, false)
    local role_collection = role.get_instance()
    for _, v in ipairs(role_ids) do
        local temp_role_data = role_collection:get_role_data_by_id(v)
        -- 缓存中role_data是个大表，只需要引用其中的RolePrivilege
        local temp_priv = parse_priv_data(temp_role_data.RolePrivilege)
        -- 转换为 {key = boolean} 的格式
        res = res + Privilege.new_from_data(temp_priv)
    end
    return res
end

function Privilege:to_array()
    local res = {}
    for key, value in pairs(self) do
        if value == true then
            table.insert(res, key:sub(3))
        end
    end
    return res
end

local privilege_map = {
    ReadOnly = 2 ^ 0,
    DiagnoseMgmt = 2 ^ 1,
    SecurityMgmt = 2 ^ 2,
    BasicSetting = 2 ^ 3,
    UserMgmt = 2 ^ 4,
    PowerMgmt = 2 ^ 5,
    VMMMgmt = 2 ^ 6,
    KVMMgmt = 2 ^ 7,
    ConfigureSelf = 2 ^ 8
}

function Privilege:num_to_array(privilege_num)
    local privilege = {}
    for k, v in pairs(privilege_map) do
        if tonumber(privilege_num) & tonumber(v) ~= 0 then
            table.insert(privilege, tostring(k))
        end
    end
    return privilege
end

return Privilege
