import { __assign, __awaiter, __generator } from "tslib";
import { createBackendManager } from "./BackendManager";
import { createServiceManager } from "./ServiceManager";
import { createArticleState } from "./ArticleState";
import { createArticleQuery } from "./ArticleQuery";
import { createArticleManager } from "./ArticleManager";
import { createNotificationCenter } from "./NotificationCenter";
import { createConnectionManager } from "./ConnectionManager";
import { createArticleRegistry } from "./ArticleRegistry";
import { createProjectManager } from "./ProjectManager";
import { createOperationResultHandler } from "./OperationResultHandler";
import { createHooks } from "./Hooks";
import { createSourceRegistry } from "./SourceRegistry";
import { createLocalizationManager, } from "./LocalizationManager";
import { NoopApplicationState } from "./NoopApplicationState";
import { createApplicationStateManager } from "./ApplicationStateManager";
import { createScheduler } from "./Scheduler";
export var BackendRegistry = createBackendManager();
export var createSession = function (params) {
    if (params === void 0) { params = {}; }
    var services = createServices(params);
    return createSessionAPI(services);
};
export var createServices = function (_a) {
    var language = _a.language, currency = _a.currency, locale = _a.locale, _b = _a.applicationState, applicationState = _b === void 0 ? NoopApplicationState : _b;
    var hooks = createHooks();
    var connectionManager = createConnectionManager();
    var notificationCenter = createNotificationCenter();
    var localizationManager = createLocalizationManager({
        language: language,
        currency: currency,
        locale: locale,
    }, notificationCenter);
    var serviceManager = createServiceManager(BackendRegistry);
    var articleState = createArticleState();
    var articleQuery = createArticleQuery(articleState);
    var scheduler = createScheduler(articleQuery);
    var articleRegistry = createArticleRegistry(serviceManager, articleState);
    var operationResultHandler = createOperationResultHandler(articleRegistry, articleQuery, notificationCenter, hooks);
    var articleManager = createArticleManager(serviceManager, articleState, articleQuery, operationResultHandler, applicationState);
    var sourceRegistry = createSourceRegistry(serviceManager, articleQuery, scheduler);
    var projectManager = createProjectManager(serviceManager, articleQuery, articleManager, operationResultHandler, hooks, sourceRegistry, connectionManager, localizationManager);
    return {
        localizationManager: localizationManager,
        operationResultHandler: operationResultHandler,
        hooks: hooks,
        scheduler: scheduler,
        notificationCenter: notificationCenter,
        backendManager: BackendRegistry,
        serviceManager: serviceManager,
        articleState: articleState,
        articleQuery: articleQuery,
        articleManager: articleManager,
        connectionManager: connectionManager,
        articleRegistry: articleRegistry,
        projectManager: projectManager,
        sourceRegistry: sourceRegistry,
        applicationState: applicationState,
    };
};
export var createSessionAPI = function (services) {
    var applicationStateManager = createApplicationStateManager(services.applicationState, services.hooks, services.notificationCenter);
    var destroy = function () { return __awaiter(void 0, void 0, void 0, function () {
        return __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 __awaiter(void 0, void 0, void 0, function () {
        return __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 __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({}, services.articleQuery), services.serviceManager), services.articleManager), services.serviceManager), services.connectionManager), services.projectManager), 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 });
};
