-- 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 service = require 'iam.service'
local base_msg = require 'messages.base'
local cls_mng = require 'mc.class_mgnt'
local enum = require 'class.types.types'
local web_session = require 'session.domain.session_collection_web'
local cli_session = require 'session.domain.session_collection_cli'
local vnc_session = require 'session.domain.session_collection_vnc'
local kvm_session = require 'session.domain.session_collection_kvm'
local redfish_session = require 'session.domain.session_collection_redfish'
local session_mdb = class()

local session_type_string_map = {
    ['GUI'] = web_session,
    ['Redfish'] = redfish_session,
    ['CLI'] = cli_session,
    ['KVM'] = kvm_session,
    ['VNC'] = vnc_session,
}

function session_mdb:ctor(session_service)
    self.m_session_service = session_service
    -- self.m_session_collection = session_service.m_session_collection
    self.m_sessions = {}
    self.m_mdb_cls = cls_mng("Session")
end

function session_mdb:regist_session_signals()
    self.m_new_unregist_handle = self.m_session_service.m_session_added:on(function(...)
        self:new_session_to_mdb_tree(...)
    end)
    self.m_delete_unregist_handle = self.m_session_service.m_session_removed:on(function(...)
        self:delete_session_from_mdb_tree(...)
    end)
end

function session_mdb:new_session_to_mdb_tree(session_info)
    local session = service:CreateSession(session_info.session_id, function(session)
        session.ClientOriginIPAddress = session_info.client_origin_ip_address
        session.CreatedTime = session_info.created_time
        session.SessionId = session_info.session_id
        session.OemSessionType = session_info.oem_session_type
        session.AccountPassword = session_info.account_password
        session.SessionType = session_info.session_type
        session.UserName = session_info.user_name
        session.LastLoginIp = session_info.last_login_ip
        session.LastLoginTime = session_info.last_login_time
        session.AuthType = session_info.auth_type
        session.Role = session_info.role_id
        session.Privileges = session_info.privileges
        session.AccountId = session_info.account_id
        session.BrowserType = session_info.browser_type
    end)
    self.m_sessions[#self.m_sessions + 1] = session
end

function session_mdb:delete_session_from_mdb_tree(session_id)
    local target_index = nil
    for index, session_obj in pairs(self.m_sessions) do
        if session_obj.SessionId == session_id then
            target_index = index
            break
        end
    end
    if target_index == nil then
        log:error('delete sessions((%s)) failed, invalid session id', session_id)
        error(base_msg.InternalError())
    end
    local removed_type = self.m_sessions[target_index].SessionType
    self.m_mdb_cls:remove(self.m_sessions[target_index])
    table.remove(self.m_sessions, target_index)
    session_type_string_map[removed_type].new():delete(session_id)
    return removed_type
end

return singleton(session_mdb)
