"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "BootTask", {
    enumerable: true,
    get: function() {
        return BootTask;
    }
});
const _mongoose = /*#__PURE__*/ _interop_require_wildcard(require("mongoose"));
const _serverenv = require("../server.env");
const _containertokens = require("../container.tokens");
const _serverconstants = require("../server.constants");
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {
        __proto__: null
    };
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
class BootTask {
    logger;
    taskManagerService;
    serverTasks;
    settingsStore;
    settingsService;
    multerService;
    printerSocketStore;
    printerFilesStore;
    permissionService;
    roleService;
    userService;
    pluginRepositoryCache;
    floorStore;
    pluginFirmwareUpdateService;
    clientBundleService;
    configService;
    isTypeormMode;
    typeormService;
    constructor({ loggerFactory, serverTasks, settingsService, settingsStore, multerService, printerSocketStore, printerFilesStore, permissionService, roleService, userService, taskManagerService, pluginRepositoryCache, floorStore, pluginFirmwareUpdateService, clientBundleService, configService, typeormService, isTypeormMode }){
        this.isTypeormMode = isTypeormMode;
        this.logger = loggerFactory(BootTask.name);
        this.serverTasks = serverTasks;
        this.settingsService = settingsService;
        this.settingsStore = settingsStore;
        this.multerService = multerService;
        this.printerSocketStore = printerSocketStore;
        this.printerFilesStore = printerFilesStore;
        this.permissionService = permissionService;
        this.roleService = roleService;
        this.userService = userService;
        this.taskManagerService = taskManagerService;
        this.pluginRepositoryCache = pluginRepositoryCache;
        this.floorStore = floorStore;
        this.pluginFirmwareUpdateService = pluginFirmwareUpdateService;
        this.clientBundleService = clientBundleService;
        this.configService = configService;
        this.typeormService = typeormService;
    }
    async runOnce() {
        this.taskManagerService.registerJobOrTask(this.serverTasks.SERVER_BOOT_TASK);
        this.logger.log("Running boot task once.");
        await this.run();
    }
    async run() {
        if (this.isTypeormMode) {
            await this.typeormService.createConnection();
        } else {
            try {
                await this.createConnection();
                await this.migrateDatabase();
            } catch (e) {
                if (e instanceof _mongoose.default.Error) {
                    if (!e.message.includes("Can't call `openUri()` on an active connection with different connection strings.")) {
                        if (e.message.includes("ECONNREFUSED")) {
                            this.logger.error("Database connection timed-out. Retrying in 5000.");
                        } else {
                            this.logger.error(`Database connection error: ${e.message}`);
                        }
                        this.taskManagerService.scheduleDisabledJob(_containertokens.DITokens.bootTask, false);
                        return;
                    }
                }
            }
        }
        this.logger.log("Loading and synchronizing Server Settings");
        await this.settingsStore.loadSettings();
        this.logger.log("Synchronizing user permission and roles definition");
        await this.permissionService.syncPermissions();
        await this.roleService.syncRoles();
        const isDemoMode = this.configService.isDemoMode();
        if (isDemoMode) {
            this.logger.warn(`Starting in demo mode due to ${_serverconstants.AppConstants.OVERRIDE_IS_DEMO_MODE}`);
            await this.createOrUpdateDemoAccount();
            this.logger.warn(`Setting loginRequired=true and registration=false due to ${_serverconstants.AppConstants.OVERRIDE_IS_DEMO_MODE}`);
            await this.settingsStore.setLoginRequired(true);
            await this.settingsStore.setRegistrationEnabled(false);
        } else {
            const loginRequired = this.configService.get(_serverconstants.AppConstants.OVERRIDE_LOGIN_REQUIRED, null);
            if (loginRequired !== null) {
                this.logger.warn(`Setting login required due to ${_serverconstants.AppConstants.OVERRIDE_LOGIN_REQUIRED}`);
                await this.settingsStore.setLoginRequired(loginRequired === "true");
            }
            const registrationEnabled = this.configService.get(_serverconstants.AppConstants.OVERRIDE_REGISTRATION_ENABLED, null);
            if (registrationEnabled !== null) {
                this.logger.warn(`Setting registration enabled due to ${_serverconstants.AppConstants.OVERRIDE_REGISTRATION_ENABLED}`);
                await this.settingsStore.setRegistrationEnabled(registrationEnabled === "true");
            }
        }
        const overrideJwtSecret = this.configService.get(_serverconstants.AppConstants.OVERRIDE_JWT_SECRET, undefined);
        const overrideJwtExpiresIn = this.configService.get(_serverconstants.AppConstants.OVERRIDE_JWT_EXPIRES_IN, undefined);
        await this.settingsStore.persistOptionalCredentialSettings(overrideJwtSecret, overrideJwtExpiresIn);
        this.logger.log("Clearing upload folder");
        this.multerService.clearUploadsFolder();
        this.logger.log("Loading printer sockets");
        await this.printerSocketStore.loadPrinterSockets();
        this.logger.log("Loading files store");
        await this.printerFilesStore.loadFilesStore();
        this.logger.log("Loading floor store");
        await this.floorStore.loadStore();
        if (process.env.SAFEMODE_ENABLED === "true") {
            this.logger.warn("Starting in safe mode due to SAFEMODE_ENABLED");
        } else {
            this.serverTasks.BOOT_TASKS.forEach((task)=>{
                this.taskManagerService.registerJobOrTask(task);
            });
        }
        this.taskManagerService.disableJob(_containertokens.DITokens.bootTask, false);
    }
    async createOrUpdateDemoAccount() {
        const demoUsername = this.configService.get(_serverconstants.AppConstants.OVERRIDE_DEMO_USERNAME, _serverconstants.AppConstants.DEFAULT_DEMO_USERNAME);
        const demoPassword = this.configService.get(_serverconstants.AppConstants.OVERRIDE_DEMO_PASSWORD, _serverconstants.AppConstants.DEFAULT_DEMO_PASSWORD);
        const demoRole = this.configService.get(_serverconstants.AppConstants.OVERRIDE_DEMO_ROLE, _serverconstants.AppConstants.DEFAULT_DEMO_ROLE);
        const adminRole = this.roleService.getRoleByName(demoRole);
        const demoUserId = await this.userService.getDemoUserId();
        if (!demoUserId) {
            await this.userService.register({
                username: demoUsername,
                password: demoPassword,
                isDemoUser: true,
                isVerified: true,
                isRootUser: false,
                needsPasswordChange: false,
                roles: [
                    adminRole.id
                ]
            });
            this.logger.log("Created demo account");
        } else {
            await this.userService.setVerifiedById(demoUserId, true);
            await this.userService.setIsRootUserById(demoUserId, false);
            await this.userService.updatePasswordUnsafeByUsername(demoUsername, demoPassword);
            await this.userService.setUserRoleIds(demoUserId, [
                adminRole.id
            ]);
            this.logger.log("Updated demo account");
        }
    }
    async createConnection() {
        if (!this.isTypeormMode) {
            const envUrl = (0, _serverenv.fetchMongoDBConnectionString)();
            await (0, _mongoose.connect)(envUrl, {
                serverSelectionTimeoutMS: 1500
            });
            await (0, _mongoose.syncIndexes)();
        }
    }
    async migrateDatabase() {
        if (!this.isTypeormMode) {
            await (0, _serverenv.runMigrations)(_mongoose.default.connection.db, _mongoose.default.connection.getClient());
        }
    }
}

//# sourceMappingURL=boot.task.js.map