"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareElectronApp = exports.normalizeAppName = void 0;
const crypto = __importStar(require("crypto"));
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const log = __importStar(require("loglevel"));
const helpers_1 = require("../helpers/helpers");
const parseUtils_1 = require("../utils/parseUtils");
const constants_1 = require("../constants");
/**
 * Only picks certain app args to pass to nativefier.json
 */
function pickElectronAppArgs(options) {
    var _a;
    return {
        accessibilityPrompt: options.nativefier.accessibilityPrompt,
        alwaysOnTop: options.nativefier.alwaysOnTop,
        appBundleId: options.packager.appBundleId,
        appCategoryType: options.packager.appCategoryType,
        appCopyright: options.packager.appCopyright,
        appVersion: options.packager.appVersion,
        arch: options.packager.arch,
        asar: options.packager.asar,
        backgroundColor: options.nativefier.backgroundColor,
        basicAuthPassword: options.nativefier.basicAuthPassword,
        basicAuthUsername: options.nativefier.basicAuthUsername,
        blockExternalUrls: options.nativefier.blockExternalUrls,
        bounce: options.nativefier.bounce,
        browserwindowOptions: options.nativefier.browserwindowOptions,
        buildDate: new Date().getTime(),
        buildVersion: options.packager.buildVersion,
        clearCache: options.nativefier.clearCache,
        counter: options.nativefier.counter,
        crashReporter: options.nativefier.crashReporter,
        darwinDarkModeSupport: options.packager.darwinDarkModeSupport,
        derefSymlinks: options.packager.derefSymlinks,
        disableContextMenu: options.nativefier.disableContextMenu,
        disableDevTools: options.nativefier.disableDevTools,
        disableGpu: options.nativefier.disableGpu,
        disableOldBuildWarning: options.nativefier.disableOldBuildWarning,
        diskCacheSize: options.nativefier.diskCacheSize,
        download: options.packager.download,
        electronVersionUsed: options.packager.electronVersion,
        enableEs3Apis: options.nativefier.enableEs3Apis,
        executableName: options.packager.executableName,
        fastQuit: options.nativefier.fastQuit,
        fileDownloadOptions: options.nativefier.fileDownloadOptions,
        flashPluginDir: options.nativefier.flashPluginDir,
        fullScreen: options.nativefier.fullScreen,
        globalShortcuts: options.nativefier.globalShortcuts,
        height: options.nativefier.height,
        helperBundleId: options.packager.helperBundleId,
        hideWindowFrame: options.nativefier.hideWindowFrame,
        ignoreCertificate: options.nativefier.ignoreCertificate,
        ignoreGpuBlacklist: options.nativefier.ignoreGpuBlacklist,
        insecure: options.nativefier.insecure,
        internalUrls: options.nativefier.internalUrls,
        isUpgrade: options.packager.upgrade,
        junk: options.packager.junk,
        lang: options.nativefier.lang,
        maximize: options.nativefier.maximize,
        maxHeight: options.nativefier.maxHeight,
        maxWidth: options.nativefier.maxWidth,
        minHeight: options.nativefier.minHeight,
        minWidth: options.nativefier.minWidth,
        name: (_a = options.packager.name) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_APP_NAME,
        nativefierVersion: options.nativefier.nativefierVersion,
        osxNotarize: options.packager.osxNotarize,
        osxSign: options.packager.osxSign,
        portable: options.packager.portable,
        processEnvs: options.nativefier.processEnvs,
        protocols: options.packager.protocols,
        proxyRules: options.nativefier.proxyRules,
        prune: options.packager.prune,
        quiet: options.packager.quiet,
        showMenuBar: options.nativefier.showMenuBar,
        singleInstance: options.nativefier.singleInstance,
        strictInternalUrls: options.nativefier.strictInternalUrls,
        targetUrl: options.packager.targetUrl,
        titleBarStyle: options.nativefier.titleBarStyle,
        tray: options.nativefier.tray,
        usageDescription: options.packager.usageDescription,
        userAgent: options.nativefier.userAgent,
        userAgentHonest: options.nativefier.userAgentHonest,
        versionString: options.nativefier.versionString,
        width: options.nativefier.width,
        widevine: options.nativefier.widevine,
        win32metadata: options.packager.win32metadata,
        x: options.nativefier.x,
        y: options.nativefier.y,
        zoom: options.nativefier.zoom,
        // OLD_BUILD_WARNING_TEXT is an undocumented env. var to let *packagers*
        // tweak the message shown on warning about an old build, to something
        // more tailored to their audience (who might not even know Nativefier).
        // See https://github.com/kelyvin/Google-Messages-For-Desktop/issues/34#issuecomment-812731144
        // and https://github.com/nativefier/nativefier/issues/1131#issuecomment-812646988
        oldBuildWarningText: process.env.OLD_BUILD_WARNING_TEXT || '',
    };
}
async function maybeCopyScripts(srcs, dest) {
    if (!srcs || srcs.length === 0) {
        log.debug('No files to inject, skipping copy.');
        return;
    }
    const supportedInjectionExtensions = ['.css', '.js'];
    log.debug(`Copying ${srcs.length} files to inject in app.`);
    for (const src of srcs) {
        if (!fs.existsSync(src)) {
            throw new Error(`File ${src} not found. Note that Nativefier expects *local* files, not URLs.`);
        }
        if (supportedInjectionExtensions.indexOf(path.extname(src)) < 0) {
            log.warn('Skipping unsupported injection file', src);
            continue;
        }
        const postFixHash = (0, helpers_1.generateRandomSuffix)();
        const destFileName = `inject-${postFixHash}${path.extname(src)}`;
        const destPath = path.join(dest, 'inject', destFileName);
        log.debug(`Copying injection file "${src}" to "${destPath}"`);
        await fs.copy(src, destPath);
    }
}
/**
 * Use a basic 6-character hash to prevent collisions. The hash is deterministic url & name,
 * so that an upgrade (same URL) of an app keeps using the same appData folder.
 * Warning! Changing this normalizing & hashing will change the way appNames are generated,
 *          changing appData folder, and users will get logged out of their apps after an upgrade.
 */
function normalizeAppName(appName, url) {
    const hash = crypto.createHash('md5');
    hash.update(url);
    const postFixHash = hash.digest('hex').substring(0, 6);
    const normalized = appName
        .toLowerCase()
        .replace(/[,:.]/g, '')
        .replace(/[\s_]/g, '-');
    return `${normalized}-nativefier-${postFixHash}`;
}
exports.normalizeAppName = normalizeAppName;
function changeAppPackageJsonName(appPath, name, url) {
    const packageJsonPath = path.join(appPath, '/package.json');
    const packageJson = (0, parseUtils_1.parseJson)(fs.readFileSync(packageJsonPath).toString());
    if (!packageJson) {
        throw new Error(`Could not load package.json from ${packageJsonPath}`);
    }
    const normalizedAppName = normalizeAppName(name, url);
    packageJson.name = normalizedAppName;
    log.debug(`Updating ${packageJsonPath} 'name' field to ${normalizedAppName}`);
    fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
    return normalizedAppName;
}
/**
 * Creates a temporary directory, copies the './app folder' inside,
 * and adds a text file with the app configuration.
 */
async function prepareElectronApp(src, dest, options) {
    log.debug(`Copying electron app from ${src} to ${dest}`);
    try {
        await fs.copy(src, dest);
    }
    catch (err) {
        throw `Error copying electron app from ${src} to temp dir ${dest}. Error: ${err.message}`;
    }
    const appJsonPath = path.join(dest, '/nativefier.json');
    const pickedOptions = pickElectronAppArgs(options);
    log.debug(`Writing app config to ${appJsonPath}`, pickedOptions);
    await fs.writeFile(appJsonPath, JSON.stringify(pickedOptions));
    if (options.nativefier.bookmarksMenu) {
        const bookmarksJsonPath = path.join(dest, '/bookmarks.json');
        try {
            await fs.copy(options.nativefier.bookmarksMenu, bookmarksJsonPath);
        }
        catch (err) {
            log.error('Error copying bookmarks menu config file.', err);
        }
    }
    try {
        await maybeCopyScripts(options.nativefier.inject, dest);
    }
    catch (err) {
        log.error('Error copying injection files.', err);
    }
    const normalizedAppName = changeAppPackageJsonName(dest, options.packager.name, options.packager.targetUrl);
    options.packager.appBundleId = `com.electron.nativefier.${normalizedAppName}`;
}
exports.prepareElectronApp = prepareElectronApp;
//# sourceMappingURL=prepareElectronApp.js.map