"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var BackendManager_1 = require("./BackendManager");
var ServiceManager_1 = require("./ServiceManager");
var ArticleState_1 = require("./ArticleState");
var ArticleQuery_1 = require("./ArticleQuery");
var ArticleManager_1 = require("./ArticleManager");
var NotificationCenter_1 = require("./NotificationCenter");
var ConnectionManager_1 = require("./ConnectionManager");
var ArticleRegistry_1 = require("./ArticleRegistry");
var ProjectManager_1 = require("./ProjectManager");
var OperationResultHandler_1 = require("./OperationResultHandler");
var Hooks_1 = require("./Hooks");
var SourceRegistry_1 = require("./SourceRegistry");
var LocalizationManager_1 = require("./LocalizationManager");
var NoopApplicationState_1 = require("./NoopApplicationState");
var ApplicationStateManager_1 = require("./ApplicationStateManager");
var Scheduler_1 = require("./Scheduler");
exports.BackendRegistry = BackendManager_1.createBackendManager();
exports.createSession = function (params) {
    if (params === void 0) { params = {}; }
    var services = exports.createServices(params);
    return exports.createSessionAPI(services);
};
exports.createServices = function (_a) {
    var language = _a.language, currency = _a.currency, locale = _a.locale, _b = _a.applicationState, applicationState = _b === void 0 ? NoopApplicationState_1.NoopApplicationState : _b;
    var hooks = Hooks_1.createHooks();
    var connectionManager = ConnectionManager_1.createConnectionManager();
    var notificationCenter = NotificationCenter_1.createNotificationCenter();
    var localizationManager = LocalizationManager_1.createLocalizationManager({
        language: language,
        currency: currency,
        locale: locale,
    }, notificationCenter);
    var serviceManager = ServiceManager_1.createServiceManager(exports.BackendRegistry);
    var articleState = ArticleState_1.createArticleState();
    var articleQuery = ArticleQuery_1.createArticleQuery(articleState);
    var scheduler = Scheduler_1.createScheduler(articleQuery);
    var articleRegistry = ArticleRegistry_1.createArticleRegistry(serviceManager, articleState);
    var operationResultHandler = OperationResultHandler_1.createOperationResultHandler(articleRegistry, articleQuery, notificationCenter, hooks);
    var articleManager = ArticleManager_1.createArticleManager(serviceManager, articleState, articleQuery, operationResultHandler, applicationState);
    var sourceRegistry = SourceRegistry_1.createSourceRegistry(serviceManager, articleQuery, scheduler);
    var projectManager = ProjectManager_1.createProjectManager(serviceManager, articleQuery, articleManager, operationResultHandler, hooks, sourceRegistry, connectionManager, localizationManager);
    return {
        localizationManager: localizationManager,
        operationResultHandler: operationResultHandler,
        hooks: hooks,
        scheduler: scheduler,
        notificationCenter: notificationCenter,
        backendManager: exports.BackendRegistry,
        serviceManager: serviceManager,
        articleState: articleState,
        articleQuery: articleQuery,
        articleManager: articleManager,
        connectionManager: connectionManager,
        articleRegistry: articleRegistry,
        projectManager: projectManager,
        sourceRegistry: sourceRegistry,
        applicationState: applicationState,
    };
};
exports.createSessionAPI = function (services) {
    var applicationStateManager = ApplicationStateManager_1.createApplicationStateManager(services.applicationState, services.hooks, services.notificationCenter);
    var destroy = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    applicationStateManager.destroy();
                    services.notificationCenter.destroy();
                    return [4 /*yield*/, services.hooks.beforeDestroy.emit()];
                case 1:
                    _a.sent();
                    return [4 /*yield*/, services.connectionManager.closeAllConnections()];
                case 2:
                    _a.sent();
                    return [2 /*return*/];
            }
        });
    }); };
    var reset = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, services.articleManager.deleteArticles(services.articleQuery.getAllComIds())];
                case 1:
                    _a.sent();
                    return [2 /*return*/];
            }
        });
    }); };
    return tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, services.articleQuery), services.serviceManager), services.articleManager), services.serviceManager), services.connectionManager), services.projectManager), exports.BackendRegistry), services.operationResultHandler), services.sourceRegistry), services.localizationManager), { hooks: services.hooks, scheduleArticleOperation: services.scheduler.queueOperation, getApplicationState: services.applicationState.getState.bind(services.applicationState), getApplicationStateValue: services.applicationState.getValue.bind(services.applicationState), setApplicationState: services.applicationState.setState.bind(services.applicationState), setApplicationStateValue: services.applicationState.setValue.bind(services.applicationState), destroy: destroy, sendNotification: services.notificationCenter.send, subscribe: services.notificationCenter.subscribe, onAnyEvent: services.notificationCenter.any, on: services.notificationCenter.on, unsubscribe: services.notificationCenter.unsubscribe, reset: reset });
};
