"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "ServerHost", {
    enumerable: true,
    get: function() {
        return ServerHost;
    }
});
const _express = /*#__PURE__*/ _interop_require_default(require("express"));
const _mongoose = /*#__PURE__*/ _interop_require_default(require("mongoose"));
const _connecthistoryapifallback = /*#__PURE__*/ _interop_require_default(require("connect-history-api-fallback"));
const _awilixexpress = require("awilix-express");
const _path = require("path");
const _exceptionfilter = require("./middleware/exception.filter");
const _serverenv = require("./server.env");
const _runtimeexceptions = require("./exceptions/runtime.exceptions");
const _serverconstants = require("./server.constants");
const _fsutils = require("./utils/fs.utils");
const _envutils = require("./utils/env.utils");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
class ServerHost {
    bootTask;
    taskManagerService;
    socketIoGateway;
    appInstance = null;
    configService;
    typeormService;
    settingsStore;
    isTypeormMode;
    logger;
    constructor({ loggerFactory, bootTask, taskManagerService, socketIoGateway, configService, typeormService, isTypeormMode, settingsStore }){
        this.logger = loggerFactory(ServerHost.name);
        this.bootTask = bootTask;
        this.taskManagerService = taskManagerService;
        this.socketIoGateway = socketIoGateway;
        this.configService = configService;
        this.typeormService = typeormService;
        this.settingsStore = settingsStore;
        this.isTypeormMode = isTypeormMode;
    }
    async boot(app, quick_boot = false, listenRequests = true) {
        if (!this.isTypeormMode) {
            _mongoose.default.set("strictQuery", true);
        }
        this.appInstance = app;
        this.serveControllerRoutes(this.appInstance);
        if (!quick_boot) {
            await this.bootTask.runOnce();
        }
        if (listenRequests) return this.httpListen();
    }
    hasConnected() {
        if (this.isTypeormMode) {
            return this.typeormService.hasConnected();
        } else {
            return _mongoose.default.connections[0].readyState;
        }
    }
    serveControllerRoutes(app) {
        const routePath = "./controllers";
        app.use((req, res, next)=>{
            if (!req.originalUrl.startsWith("/api") && !req.originalUrl.startsWith("/socket.io")) {
                (0, _connecthistoryapifallback.default)()(req, res, next);
            } else {
                next();
            }
        }).use((0, _awilixexpress.loadControllers)(`${routePath}/*.controller.*`, {
            cwd: __dirname,
            ignore: "**/*.map"
        })).use(_exceptionfilter.exceptionFilter);
        const nextClientPath = (0, _path.join)((0, _fsutils.superRootPath)(), "node_modules", _serverconstants.AppConstants.clientNextPackageName, "dist");
        const bundleDistPath = (0, _path.join)((0, _fsutils.superRootPath)(), _serverconstants.AppConstants.defaultClientBundleStorage, "dist");
        const backupClientPath = (0, _path.join)((0, _fsutils.superRootPath)(), "node_modules", _serverconstants.AppConstants.clientPackageName, "dist");
        app.use((req, res, next)=>{
            if (this.isClientNextEnabled()) {
                _express.default.static(nextClientPath)(req, res, next);
            } else {
                next();
            }
        });
        app.use(_express.default.static(bundleDistPath));
        app.use(_express.default.static(backupClientPath));
        app.get("*", (req, res)=>{
            const path = req.originalUrl;
            let resource = "MVC";
            if (path.startsWith("/socket.io") || path.startsWith("/api") || path.startsWith("/plugins")) {
                resource = "API";
            } else if (path.endsWith(".min.js")) {
                resource = "client-bundle";
            }
            this.logger.error(`${resource} resource at '${path}' was not found`);
            if (!path.startsWith("/socket.io")) {
                throw new _runtimeexceptions.NotFoundException(`${resource} resource was not found`, path);
            }
        }).use(_exceptionfilter.exceptionFilter);
    }
    isClientNextEnabled() {
        const settings = this.settingsStore.getServerSettings();
        return settings.experimentalClientSupport;
    }
    async httpListen() {
        const port = (0, _serverenv.fetchServerPort)();
        if (!(0, _envutils.isProductionEnvironment)() && this.configService.get(_serverconstants.AppConstants.debugRoutesKey, "false") === "true") {
            const expressListRoutes = require("express-list-routes");
            expressListRoutes(this.appInstance, {
                prefix: "/"
            });
        }
        if (!port || Number.isNaN(parseInt(port))) {
            throw new Error("The FDM Server requires a numeric port input argument to run");
        }
        const hostOrFqdn = "0.0.0.0";
        const server = this.appInstance.listen(parseInt(port), hostOrFqdn, ()=>{
            this.logger.log(`Server started... open it at http://127.0.0.1:${port}`);
        });
        this.socketIoGateway.attachServer(server);
    }
}

//# sourceMappingURL=server.host.js.map