"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var _this = this;
Object.defineProperty(exports, "__esModule", { value: true });
var electron_1 = require("electron");
var WindowStateKeeper = require("electron-window-state");
var fileUrl = require("file-url");
var fs = require("fs-extra");
var minimist = require("minimist");
var path = require("path");
var about = require("./js/about");
var appInit = require("./js/appInit");
var config = require("./js/config");
var environment = require("./js/environment");
var initRaygun = require("./js/initRaygun");
var lifecycle = require("./js/lifecycle");
var util = require("./js/util");
var windowManager = require("./js/window-manager");
var CertificateVerifyProcManager_1 = require("./lib/CertificateVerifyProcManager");
var download_1 = require("./lib/download");
var eventType_1 = require("./lib/eventType");
var LocalAccountDeletion_1 = require("./lib/LocalAccountDeletion");
var SingleSignOn_1 = require("./lib/SingleSignOn");
var webViewFocus_1 = require("./lib/webViewFocus");
var locale = require("./locale/locale");
var developer_1 = require("./menu/developer");
var systemMenu = require("./menu/system");
var TrayHandler_1 = require("./menu/TrayHandler");
var ConfigurationPersistence_1 = require("./settings/ConfigurationPersistence");
var SettingsType_1 = require("./settings/SettingsType");
var util_1 = require("./util/");
var APP_PATH = electron_1.app.getAppPath();
var INDEX_HTML = path.join(APP_PATH, 'renderer', 'index.html');
var LOG_DIR = path.join(electron_1.app.getPath('userData'), 'logs');
var PRELOAD_JS = path.join(APP_PATH, 'dist', 'js', 'preload.js');
var PRELOAD_RENDERER_JS = path.join(APP_PATH, 'renderer', 'static', 'webview-preload.js');
var WRAPPER_CSS = path.join(APP_PATH, 'css', 'wrapper.css');
util_1.LogFactory.LOG_FILE_PATH = LOG_DIR;
util_1.LogFactory.LOG_FILE_NAME = 'electron.log';
var logger = util_1.LogFactory.getLogger('main.ts', { forceEnable: true });
var argv = minimist(process.argv.slice(1));
var BASE_URL = environment.web.getWebappUrl(argv.env);
var ICON = "wire." + (environment.platform.IS_WINDOWS ? 'ico' : 'png');
var ICON_PATH = path.join(APP_PATH, 'img', ICON);
var tray;
var isFullScreen = false;
var isQuitting = false;
var main;
var bindIpcEvents = function () {
    electron_1.ipcMain.on(eventType_1.EVENT_TYPE.ACTION.SAVE_PICTURE, function (event, fileName, bytes) { return __awaiter(_this, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4, download_1.download(fileName, bytes)];
                case 1:
                    _a.sent();
                    return [2];
            }
        });
    }); });
    electron_1.ipcMain.on(eventType_1.EVENT_TYPE.ACTION.NOTIFICATION_CLICK, function () {
        windowManager.showPrimaryWindow();
    });
    electron_1.ipcMain.on(eventType_1.EVENT_TYPE.UI.BADGE_COUNT, function (event, count) {
        tray.showUnreadCount(main, count);
    });
    electron_1.ipcMain.on(eventType_1.EVENT_TYPE.ACCOUNT.DELETE_DATA, LocalAccountDeletion_1.deleteAccount);
    electron_1.ipcMain.on(eventType_1.EVENT_TYPE.WRAPPER.RELAUNCH, lifecycle.relaunch);
    electron_1.ipcMain.on(eventType_1.EVENT_TYPE.ABOUT.SHOW, about.showWindow);
};
var checkConfigV0FullScreen = function (mainWindowState) {
    if (typeof mainWindowState.isMaximized === 'undefined' && isFullScreen === true) {
        main.maximize();
    }
};
var initWindowStateKeeper = function () {
    var loadedWindowBounds = ConfigurationPersistence_1.settings.restore(SettingsType_1.SettingsType.WINDOW_BOUNDS, {
        height: config.WINDOW.MAIN.DEFAULT_HEIGHT,
        width: config.WINDOW.MAIN.DEFAULT_WIDTH,
    });
    var showInFullScreen = ConfigurationPersistence_1.settings.restore(SettingsType_1.SettingsType.FULL_SCREEN, 'not-set-in-v0');
    var stateKeeperOptions = {
        defaultHeight: loadedWindowBounds.height,
        defaultWidth: loadedWindowBounds.width,
        path: path.join(electron_1.app.getPath('userData'), 'config'),
    };
    if (showInFullScreen !== 'not-set-in-v0') {
        stateKeeperOptions.fullScreen = showInFullScreen;
        stateKeeperOptions.maximize = showInFullScreen;
        isFullScreen = showInFullScreen;
    }
    return WindowStateKeeper(stateKeeperOptions);
};
var showMainWindow = function (mainWindowState) {
    var showMenuBar = ConfigurationPersistence_1.settings.restore(SettingsType_1.SettingsType.SHOW_MENU_BAR, true);
    var options = {
        autoHideMenuBar: !showMenuBar,
        backgroundColor: '#f7f8fa',
        height: mainWindowState.height,
        icon: ICON_PATH,
        minHeight: config.WINDOW.MAIN.MIN_HEIGHT,
        minWidth: config.WINDOW.MAIN.MIN_WIDTH,
        show: false,
        title: config.NAME,
        titleBarStyle: 'hiddenInset',
        webPreferences: {
            backgroundThrottling: false,
            nodeIntegration: false,
            preload: PRELOAD_JS,
            webviewTag: true,
        },
        width: mainWindowState.width,
        x: mainWindowState.x,
        y: mainWindowState.y,
    };
    main = new electron_1.BrowserWindow(options);
    mainWindowState.manage(main);
    checkConfigV0FullScreen(mainWindowState);
    var baseURL = "" + BASE_URL + (BASE_URL.includes('?') ? '&' : '?') + "hl=" + locale.getCurrent();
    main.loadURL(fileUrl(INDEX_HTML) + "?env=" + encodeURIComponent(baseURL));
    if (argv.devtools) {
        main.webContents.openDevTools({ mode: 'detach' });
    }
    if (!argv.startup && !argv.hidden) {
        if (!util.isInView(main)) {
            main.center();
        }
        windowManager.setPrimaryWindowId(main.id);
        setTimeout(function () { return main.show(); }, 800);
    }
    main.on('focus', function () { return systemMenu.registerShortcuts(); });
    main.on('blur', function () { return systemMenu.unregisterShortcuts(); });
    main.webContents.on('will-navigate', function (event, url) {
        event.preventDefault();
    });
    main.webContents.on('new-window', function (event, _url) {
        event.preventDefault();
        if (typeof event.sender.viewInstanceId !== 'undefined') {
            logger.log('New window was created from a webview, aborting.');
            return;
        }
        electron_1.shell.openExternal(_url);
    });
    main.webContents.on('dom-ready', function () {
        main.webContents.insertCSS(fs.readFileSync(WRAPPER_CSS, 'utf8'));
    });
    main.on('focus', function () { return main.flashFrame(false); });
    main.on('page-title-updated', function () { return tray.showUnreadCount(main); });
    main.on('close', function (event) {
        if (!isQuitting) {
            event.preventDefault();
            logger.log('Closing window...');
            if (main.isFullScreen()) {
                logger.log('Fullscreen detected, leaving full screen before hiding...');
                main.once('leave-full-screen', function () { return main.hide(); });
                main.setFullScreen(false);
            }
            else {
                main.hide();
            }
        }
    });
    main.webContents.on('crashed', function () { return main.reload(); });
};
var handleAppEvents = function () {
    electron_1.app.on('window-all-closed', function () { return __awaiter(_this, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    if (!!environment.platform.IS_MAC_OS) return [3, 2];
                    return [4, lifecycle.quit()];
                case 1:
                    _a.sent();
                    _a.label = 2;
                case 2: return [2];
            }
        });
    }); });
    electron_1.app.on('activate', function () {
        if (main) {
            main.show();
        }
    });
    electron_1.app.on('before-quit', function () {
        ConfigurationPersistence_1.settings.persistToFile();
        isQuitting = true;
    });
    electron_1.app.on('ready', function () {
        var mainWindowState = initWindowStateKeeper();
        var appMenu = systemMenu.createMenu(isFullScreen);
        if (environment.app.IS_DEVELOPMENT) {
            appMenu.append(developer_1.menuItem);
        }
        electron_1.Menu.setApplicationMenu(appMenu);
        tray = new TrayHandler_1.TrayHandler();
        if (!environment.platform.IS_MAC_OS) {
            tray.initTray();
        }
        showMainWindow(mainWindowState);
    });
};
var renameFileExtensions = function (files, oldExtension, newExtension) {
    files
        .filter(function (file) {
        try {
            return fs.statSync(file).isFile();
        }
        catch (statError) {
            return false;
        }
    })
        .forEach(function (file) {
        if (file.endsWith(oldExtension)) {
            try {
                fs.renameSync(file, file.replace(oldExtension, newExtension));
            }
            catch (error) {
                logger.error("Failed to rename log file: \"" + error.message + "\"");
            }
        }
    });
};
var renameWebViewLogFiles = function () {
    fs.readdir(LOG_DIR, function (readError, contents) {
        if (readError) {
            return logger.log("Failed to read log directory with error: " + readError.message);
        }
        var logFiles = contents.map(function (file) { return path.join(LOG_DIR, file, config.LOG_FILE_NAME); });
        renameFileExtensions(logFiles, '.log', '.old');
    });
};
var initElectronLogFile = function () {
    renameFileExtensions([util_1.LogFactory.getFileURI()], '.log', '.old');
    fs.ensureFileSync(util_1.LogFactory.getFileURI());
};
var ElectronWrapperInit = (function () {
    function ElectronWrapperInit() {
        this.logger = util_1.LogFactory.getLogger('ElectronWrapperInit');
    }
    ElectronWrapperInit.prototype.run = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                this.logger.log('webviewProtection init');
                this.webviewProtection();
                return [2];
            });
        });
    };
    ElectronWrapperInit.prototype.webviewProtection = function () {
        var _this = this;
        var openLinkInNewWindow = function (event, url, frameName, disposition, options) {
            event.preventDefault();
            if (SingleSignOn_1.SingleSignOn.isSingleSignOnLoginWindow(frameName) && SingleSignOn_1.SingleSignOn.isBackendOrigin(url)) {
                return new SingleSignOn_1.SingleSignOn(main, event, url, options).init();
            }
            _this.logger.log("Opening an external window from a webview. URL: " + url);
            return electron_1.shell.openExternal(url);
        };
        var willNavigateInWebview = function (event, _url) {
            if (util.isMatchingHost(_url, BASE_URL)) {
                _this.logger.log("Navigating inside webview. URL: " + _url);
            }
            else {
                _this.logger.log("Preventing navigation inside WebView. URL: " + _url);
                event.preventDefault();
            }
        };
        electron_1.app.on('web-contents-created', function (webviewEvent, contents) {
            webViewFocus_1.WebViewFocus.bindTracker(webviewEvent, contents);
            switch (contents.getType()) {
                case 'window':
                    contents.on('will-attach-webview', function (event, webPreferences, params) {
                        var _url = params.src;
                        if (!util.isMatchingHost(_url, BASE_URL)) {
                            event.preventDefault();
                            _this.logger.log("Prevented to show an unauthorized <webview>. URL: " + _url);
                            return;
                        }
                        params.autosize = false;
                        params.contextIsolation = true;
                        params.plugins = false;
                        webPreferences.allowRunningInsecureContent = false;
                        webPreferences.nodeIntegration = false;
                        webPreferences.preloadURL = fileUrl(PRELOAD_RENDERER_JS);
                        webPreferences.webSecurity = true;
                    });
                    break;
                case 'webview':
                    contents.on('new-window', openLinkInNewWindow);
                    contents.on('will-navigate', willNavigateInWebview);
                    contents.session.setCertificateVerifyProc(CertificateVerifyProcManager_1.setCertificateVerifyProc);
                    var isLocalhostEnvironment = environment.getEnvironment() == environment.BackendType.LOCALHOST;
                    if (isLocalhostEnvironment) {
                        contents.session.webRequest.onHeadersReceived({
                            urls: config.BACKEND_ORIGINS.map(function (value) { return value + "/*"; }),
                        }, function (details, callback) {
                            details.responseHeaders['Access-Control-Allow-Origin'] = ['http://localhost:8081'];
                            details.responseHeaders['Access-Control-Allow-Credentials'] = ['true'];
                            callback({
                                cancel: false,
                                responseHeaders: details.responseHeaders,
                            });
                        });
                    }
                    break;
            }
        });
    };
    return ElectronWrapperInit;
}());
initRaygun.initClient();
appInit.ignoreCertificateErrorsInDevelopment();
appInit.handlePortableFlags();
lifecycle.checkSingleInstance();
lifecycle.checkForUpdate();
if (lifecycle.isFirstInstance) {
    appInit.addLinuxWorkarounds();
    bindIpcEvents();
    handleAppEvents();
    renameWebViewLogFiles();
    initElectronLogFile();
    new ElectronWrapperInit().run().catch(function (error) { return logger.error(error); });
}
//# sourceMappingURL=main.js.map