-- 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 cls_mng = require 'mc.class_mgnt'
local context = require 'mc.context'
local base_msg = require 'messages.base'


local INTERFACE_SESSION_SERVICE <const> = 'bmc.kepler.SessionService'
local session_service_mdb = class()

function session_service_mdb:ctor(session_collections)
    self.m_session_collections = session_collections
    self.m_session_configs = {}
    self.m_mdb_cls = cls_mng("Session")
end

function session_service_mdb:regist_session_signals()
    for k, v in pairs(self.m_session_collections) do
        v.m_session_config_create:on(function(...)
            self:new_session_config_to_mdb_tree(...)
        end)
        v.m_session_config_modified:on(function(...)
            self:modify_session_config_from_mdb_tree(...)
        end)
    end
end

function session_service_mdb:init()

end

session_service_mdb.watch_property_hook = {
    SessionTimeout = function(self, ctx, session_type, value)
        self.m_session_service:set_session_timeout(ctx, session_type, value)
    end,
    SessionMode = function(self, ctx, session_type, value)
        self.m_session_service:set_session_mode(ctx, session_type, value)
    end,
    SessionMaxCount = function(self, ctx, session_type, value)
        self.m_session_service:set_session_max_count(ctx, session_type, value)
    end
}

function session_service_mdb:new_session_config_to_mdb_tree(session_config)
    local session_service = service:CreateSessionService(tostring(session_config.session_type), function(session_service)
        session_service.SessionTimeout = session_config.session_timeout
        session_service.SessionMode = session_config.session_mode
        session_service.SessionMaxCount = session_config.session_maxcount
        self:watch_session_service_property(session_service)
    end)
    self.m_session_configs[session_config.session_type] = session_service
end

function session_service_mdb:watch_session_service_property(session_service)
    session_service[INTERFACE_SESSION_SERVICE].property_before_change:on(function(name, value, sender)
        if not sender then
            log:info('change the property(%s), sender is nil', name)
            return true
        end

        if not self.watch_property_hook[name] then
            log:error('change the property(%s), invalid', name)
            error(base_msg.InternalError())
        end
        log:info('change the property(%s)', name)
        local ctx = context.get_context() or context.new('WEB', 'NA', 'NA')
        self.watch_property_hook[name](self, ctx, session_service.session_type, value)
        return true
    end)
end

return singleton(session_service_mdb)
