"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var inversify_1 = require("inversify");
var arduino_daemon_impl_1 = require("./arduino-daemon-impl");
var logger_1 = require("@theia/core/lib/common/logger");
var backend_application_1 = require("@theia/core/lib/node/backend-application");
var library_service_1 = require("../common/protocol/library-service");
var boards_service_1 = require("../common/protocol/boards-service");
var library_service_server_impl_1 = require("./library-service-server-impl");
var boards_service_impl_1 = require("./boards-service-impl");
var core_service_impl_1 = require("./core-service-impl");
var core_service_1 = require("../common/protocol/core-service");
var connection_container_module_1 = require("@theia/core/lib/node/messaging/connection-container-module");
var core_client_provider_1 = require("./core-client-provider");
var core_1 = require("@theia/core");
var default_workspace_server_1 = require("./theia/workspace/default-workspace-server");
var common_1 = require("@theia/workspace/lib/common");
var sketches_service_impl_1 = require("./sketches-service-impl");
var sketches_service_1 = require("../common/protocol/sketches-service");
var config_service_1 = require("../common/protocol/config-service");
var arduino_daemon_1 = require("../common/protocol/arduino-daemon");
var monitor_service_impl_1 = require("./monitor/monitor-service-impl");
var monitor_service_1 = require("../common/protocol/monitor-service");
var monitor_client_provider_1 = require("./monitor/monitor-client-provider");
var config_service_impl_1 = require("./config-service-impl");
var env_variables_1 = require("@theia/core/lib/common/env-variables");
var env_variables_server_1 = require("./theia/env-variables/env-variables-server");
var node_filesystem_ext_1 = require("./node-filesystem-ext");
var filesystem_ext_1 = require("../common/protocol/filesystem-ext");
var examples_service_impl_1 = require("./examples-service-impl");
var examples_service_1 = require("../common/protocol/examples-service");
var executable_service_1 = require("../common/protocol/executable-service");
var executable_service_impl_1 = require("./executable-service-impl");
var output_service_1 = require("../common/protocol/output-service");
var notification_service_server_1 = require("./notification-service-server");
var protocol_1 = require("../common/protocol");
var backend_application_2 = require("./theia/core/backend-application");
var board_discovery_1 = require("./board-discovery");
exports.default = new inversify_1.ContainerModule(function (bind, unbind, isBound, rebind) {
    bind(backend_application_2.BackendApplication).toSelf().inSingletonScope();
    rebind(backend_application_1.BackendApplication).toService(backend_application_2.BackendApplication);
    // Shared config service
    bind(config_service_impl_1.ConfigServiceImpl).toSelf().inSingletonScope();
    bind(config_service_1.ConfigService).toService(config_service_impl_1.ConfigServiceImpl);
    // Note: The config service must start earlier than the daemon, hence the binding order of the BA contribution does matter.
    bind(backend_application_1.BackendApplicationContribution).toService(config_service_impl_1.ConfigServiceImpl);
    bind(core_1.ConnectionHandler).toDynamicValue(function (context) { return new core_1.JsonRpcConnectionHandler(config_service_1.ConfigServicePath, function () { return context.container.get(config_service_1.ConfigService); }); }).inSingletonScope();
    // Shared daemon 
    bind(arduino_daemon_impl_1.ArduinoDaemonImpl).toSelf().inSingletonScope();
    bind(arduino_daemon_1.ArduinoDaemon).toService(arduino_daemon_impl_1.ArduinoDaemonImpl);
    bind(backend_application_1.BackendApplicationContribution).toService(arduino_daemon_impl_1.ArduinoDaemonImpl);
    bind(core_1.ConnectionHandler).toDynamicValue(function (context) { return new core_1.JsonRpcConnectionHandler(arduino_daemon_1.ArduinoDaemonPath, function () { return context.container.get(arduino_daemon_1.ArduinoDaemon); }); }).inSingletonScope();
    // Examples service. One per backend, each connected FE gets a proxy.
    bind(connection_container_module_1.ConnectionContainerModule).toConstantValue(connection_container_module_1.ConnectionContainerModule.create(function (_a) {
        var bind = _a.bind, bindBackendService = _a.bindBackendService;
        bind(examples_service_impl_1.ExamplesServiceImpl).toSelf().inSingletonScope();
        bind(examples_service_1.ExamplesService).toService(examples_service_impl_1.ExamplesServiceImpl);
        bindBackendService(examples_service_1.ExamplesServicePath, examples_service_1.ExamplesService);
    }));
    // Exposes the executable paths/URIs to the frontend
    bind(executable_service_impl_1.ExecutableServiceImpl).toSelf().inSingletonScope();
    bind(executable_service_1.ExecutableService).toService(executable_service_impl_1.ExecutableServiceImpl);
    bind(core_1.ConnectionHandler).toDynamicValue(function (context) { return new core_1.JsonRpcConnectionHandler(executable_service_1.ExecutableServicePath, function () { return context.container.get(executable_service_1.ExecutableService); }); }).inSingletonScope();
    // Library service. Singleton per backend, each connected FE gets its proxy.
    bind(connection_container_module_1.ConnectionContainerModule).toConstantValue(connection_container_module_1.ConnectionContainerModule.create(function (_a) {
        var bind = _a.bind, bindBackendService = _a.bindBackendService;
        bind(library_service_server_impl_1.LibraryServiceImpl).toSelf().inSingletonScope();
        bind(library_service_1.LibraryService).toService(library_service_server_impl_1.LibraryServiceImpl);
        bindBackendService(library_service_1.LibraryServicePath, library_service_1.LibraryService);
    }));
    // Shared sketches service
    bind(sketches_service_impl_1.SketchesServiceImpl).toSelf().inSingletonScope();
    bind(sketches_service_1.SketchesService).toService(sketches_service_impl_1.SketchesServiceImpl);
    bind(core_1.ConnectionHandler).toDynamicValue(function (context) { return new core_1.JsonRpcConnectionHandler(sketches_service_1.SketchesServicePath, function () { return context.container.get(sketches_service_1.SketchesService); }); }).inSingletonScope();
    // Boards service. One instance per connected frontend.
    bind(connection_container_module_1.ConnectionContainerModule).toConstantValue(connection_container_module_1.ConnectionContainerModule.create(function (_a) {
        var bind = _a.bind, bindBackendService = _a.bindBackendService;
        bind(boards_service_impl_1.BoardsServiceImpl).toSelf().inSingletonScope();
        bind(boards_service_1.BoardsService).toService(boards_service_impl_1.BoardsServiceImpl);
        bindBackendService(boards_service_1.BoardsServicePath, boards_service_1.BoardsService);
    }));
    // Shared Arduino core client provider service for the backend.
    bind(core_client_provider_1.CoreClientProvider).toSelf().inSingletonScope();
    // Shared port/board discovery for the server
    bind(board_discovery_1.BoardDiscovery).toSelf().inSingletonScope();
    // Core service -> `verify` and `upload`. Singleton per BE, each FE connection gets its proxy.
    bind(connection_container_module_1.ConnectionContainerModule).toConstantValue(connection_container_module_1.ConnectionContainerModule.create(function (_a) {
        var bind = _a.bind, bindBackendService = _a.bindBackendService;
        bind(core_service_impl_1.CoreServiceImpl).toSelf().inSingletonScope();
        bind(core_service_1.CoreService).toService(core_service_impl_1.CoreServiceImpl);
        bindBackendService(core_service_1.CoreServicePath, core_service_1.CoreService);
    }));
    // #region Theia customizations
    bind(default_workspace_server_1.DefaultWorkspaceServer).toSelf().inSingletonScope();
    rebind(common_1.WorkspaceServer).toService(default_workspace_server_1.DefaultWorkspaceServer);
    bind(env_variables_server_1.EnvVariablesServer).toSelf().inSingletonScope();
    rebind(env_variables_1.EnvVariablesServer).toService(env_variables_server_1.EnvVariablesServer);
    // #endregion Theia customizations
    // Monitor client provider per connected frontend.
    bind(connection_container_module_1.ConnectionContainerModule).toConstantValue(connection_container_module_1.ConnectionContainerModule.create(function (_a) {
        var bind = _a.bind, bindBackendService = _a.bindBackendService;
        bind(monitor_client_provider_1.MonitorClientProvider).toSelf().inSingletonScope();
        bind(monitor_service_impl_1.MonitorServiceImpl).toSelf().inSingletonScope();
        bind(monitor_service_1.MonitorService).toService(monitor_service_impl_1.MonitorServiceImpl);
        bindBackendService(monitor_service_1.MonitorServicePath, monitor_service_1.MonitorService, function (service, client) {
            service.setClient(client);
            client.onDidCloseConnection(function () { return service.dispose(); });
            return service;
        });
    }));
    // File-system extension for mapping paths to URIs
    bind(node_filesystem_ext_1.NodeFileSystemExt).toSelf().inSingletonScope();
    bind(filesystem_ext_1.FileSystemExt).toService(node_filesystem_ext_1.NodeFileSystemExt);
    bind(core_1.ConnectionHandler).toDynamicValue(function (context) { return new core_1.JsonRpcConnectionHandler(filesystem_ext_1.FileSystemExtPath, function () { return context.container.get(filesystem_ext_1.FileSystemExt); }); }).inSingletonScope();
    // Output service per connection.
    bind(connection_container_module_1.ConnectionContainerModule).toConstantValue(connection_container_module_1.ConnectionContainerModule.create(function (_a) {
        var bindFrontendService = _a.bindFrontendService;
        bindFrontendService(output_service_1.OutputServicePath, output_service_1.OutputService);
    }));
    // Notify all connected frontend instances
    bind(notification_service_server_1.NotificationServiceServerImpl).toSelf().inSingletonScope();
    bind(protocol_1.NotificationServiceServer).toService(notification_service_server_1.NotificationServiceServerImpl);
    bind(core_1.ConnectionHandler).toDynamicValue(function (context) {
        return new core_1.JsonRpcConnectionHandler(protocol_1.NotificationServicePath, function (client) {
            var server = context.container.get(protocol_1.NotificationServiceServer);
            server.setClient(client);
            client.onDidCloseConnection(function () { return server.disposeClient(client); });
            return server;
        });
    }).inSingletonScope();
    // Logger for the Arduino daemon
    bind(logger_1.ILogger).toDynamicValue(function (ctx) {
        var parentLogger = ctx.container.get(logger_1.ILogger);
        return parentLogger.child('daemon');
    }).inSingletonScope().whenTargetNamed('daemon');
    // Logger for the "serial discovery".
    bind(logger_1.ILogger).toDynamicValue(function (ctx) {
        var parentLogger = ctx.container.get(logger_1.ILogger);
        return parentLogger.child('discovery');
    }).inSingletonScope().whenTargetNamed('discovery');
    // Logger for the CLI config service. From the CLI config (FS path aware), we make a URI-aware app config.
    bind(logger_1.ILogger).toDynamicValue(function (ctx) {
        var parentLogger = ctx.container.get(logger_1.ILogger);
        return parentLogger.child('config');
    }).inSingletonScope().whenTargetNamed('config');
    // Logger for the monitor service.
    bind(logger_1.ILogger).toDynamicValue(function (ctx) {
        var parentLogger = ctx.container.get(logger_1.ILogger);
        return parentLogger.child('monitor-service');
    }).inSingletonScope().whenTargetNamed('monitor-service');
});
//# sourceMappingURL=arduino-ide-backend-module.js.map