"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;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildNativefierApp = void 0;
const path = __importStar(require("path"));
const electronGet = __importStar(require("@electron/get"));
const electron_packager_1 = __importDefault(require("electron-packager"));
const fs = __importStar(require("fs-extra"));
const log = __importStar(require("loglevel"));
const buildIcon_1 = require("./buildIcon");
const helpers_1 = require("../helpers/helpers");
const upgrade_1 = require("../helpers/upgrade/upgrade");
const optionsMain_1 = require("../options/optionsMain");
const prepareElectronApp_1 = require("./prepareElectronApp");
const OPTIONS_REQUIRING_WINDOWS_FOR_WINDOWS_BUILD = [
    'icon',
    'appCopyright',
    'appVersion',
    'buildVersion',
    'versionString',
    'win32metadata',
];
/**
 * For Windows & Linux, we have to copy over the icon to the resources/app
 * folder, which the BrowserWindow is hard-coded to read the icon from
 */
async function copyIconsIfNecessary(options, appPath) {
    log.debug('Copying icons if necessary');
    if (!options.packager.icon) {
        log.debug('No icon specified in options; aborting');
        return;
    }
    if (options.packager.platform === 'darwin' ||
        options.packager.platform === 'mas') {
        if (options.nativefier.tray !== 'false') {
            //tray icon needs to be .png
            log.debug('Copying icon for tray application');
            const trayIconFileName = `tray-icon.png`;
            const destIconPath = path.join(appPath, 'icon.png');
            await fs.copy(`${path.dirname(options.packager.icon)}/${trayIconFileName}`, destIconPath);
        }
        else {
            log.debug('No copying necessary on macOS; aborting');
        }
        return;
    }
    // windows & linux: put the icon file into the app
    const destFileName = `icon${path.extname(options.packager.icon)}`;
    const destIconPath = path.join(appPath, destFileName);
    log.debug(`Copying icon ${options.packager.icon} to`, destIconPath);
    await fs.copy(options.packager.icon, destIconPath);
}
/**
 * Checks the app path array to determine if packaging completed successfully
 */
function getAppPath(appPath) {
    if (!Array.isArray(appPath)) {
        return appPath;
    }
    if (appPath.length === 0) {
        return undefined; // directory already exists and `--overwrite` not set
    }
    if (appPath.length > 1) {
        log.warn('Warning: This should not be happening, packaged app path contains more than one element:', appPath);
    }
    return appPath[0];
}
function isUpgrade(rawOptions) {
    if (rawOptions.upgrade !== undefined &&
        typeof rawOptions.upgrade === 'string' &&
        rawOptions.upgrade !== '') {
        rawOptions.upgradeFrom = rawOptions.upgrade;
        rawOptions.upgrade = true;
        return true;
    }
    return false;
}
function trimUnprocessableOptions(options) {
    if (options.packager.platform === 'win32' && !(0, helpers_1.isWindows)() && !(0, helpers_1.hasWine)()) {
        const optionsPresent = Object.entries(options)
            .filter(([key, value]) => OPTIONS_REQUIRING_WINDOWS_FOR_WINDOWS_BUILD.includes(key) && !!value)
            .map(([key]) => key);
        if (optionsPresent.length === 0) {
            return;
        }
        log.warn(`*Not* setting [${optionsPresent.join(', ')}], as couldn't find Wine.`, 'Wine is required when packaging a Windows app under on non-Windows platforms.', 'Also, note that Windows apps built under non-Windows platforms without Wine *will lack* certain', 'features, like a correct icon and process name. Do yourself a favor and install Wine, please.');
        for (const keyToUnset of optionsPresent) {
            options[keyToUnset] = undefined;
        }
    }
}
function getOSRunHelp(platform) {
    if (platform === 'win32') {
        return `the contained .exe file.`;
    }
    else if (platform === 'linux') {
        return `the contained executable file (prefixing with ./ if necessary)\nMenu/desktop shortcuts are up to you, because Nativefier cannot know where you're going to move the app. Search for "linux .desktop file" for help, or see https://wiki.archlinux.org/index.php/Desktop_entries`;
    }
    else if (platform === 'darwin') {
        return `the app bundle.`;
    }
    return '';
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
async function buildNativefierApp(rawOptions) {
    var _a, _b, _c, _d;
    // early-suppress potential logging before full options handling
    if (rawOptions.quiet) {
        log.setLevel('silent');
    }
    log.warn('\n\n    Hi! Nativefier is minimally maintained these days, and needs more hands.\n' +
        '    If you have the time & motivation, help with bugfixes and maintenance is VERY welcome.\n' +
        '    Please go to https://github.com/nativefier/nativefier and help how you can. Thanks.\n\n');
    log.info('\nProcessing options...');
    let finalOutDirectory = (_a = rawOptions.out) !== null && _a !== void 0 ? _a : process.cwd();
    if (isUpgrade(rawOptions)) {
        log.debug('Attempting to upgrade from', rawOptions.upgradeFrom);
        const oldApp = (0, upgrade_1.findUpgradeApp)(rawOptions.upgradeFrom);
        if (!oldApp) {
            throw new Error(`Could not find an old Nativfier app in "${rawOptions.upgradeFrom}"`);
        }
        rawOptions = (0, upgrade_1.useOldAppOptions)(rawOptions, oldApp);
        if (rawOptions.out === undefined && rawOptions.overwrite) {
            finalOutDirectory = oldApp.appRoot;
            rawOptions.out = (0, helpers_1.getTempDir)('appUpgrade', 0o755);
        }
    }
    log.debug('rawOptions', rawOptions);
    const options = await (0, optionsMain_1.getOptions)(rawOptions);
    log.debug('options', options);
    if (options.packager.platform === 'darwin' && (0, helpers_1.isWindows)()) {
        // electron-packager has to extract the desired electron package for the target platform.
        // For a target platform of Mac, this zip file contains symlinks. And on Windows, extracting
        // files that are symlinks need Admin permissions. So we'll check if the user is an admin, and
        // fail early if not.
        // For reference
        // https://github.com/electron/electron-packager/issues/933
        // https://github.com/electron/electron-packager/issues/1194
        // https://github.com/electron/electron/issues/11094
        if (!(0, helpers_1.isWindowsAdmin)()) {
            throw new Error('Building an app with a target platform of Mac on a Windows machine requires admin priveleges to perform. Please rerun this command in an admin command prompt.');
        }
    }
    log.info('\nPreparing Electron app...');
    const tmpPath = (0, helpers_1.getTempDir)('app', 0o755);
    await (0, prepareElectronApp_1.prepareElectronApp)(options.packager.dir, tmpPath, options);
    log.info('\nConverting icons...');
    options.packager.dir = tmpPath;
    (0, buildIcon_1.convertIconIfNecessary)(options);
    await copyIconsIfNecessary(options, tmpPath);
    options.packager.quiet = !rawOptions.verbose;
    log.info("\nPackaging... This will take a few seconds, maybe minutes if the requested Electron isn't cached yet...");
    trimUnprocessableOptions(options);
    electronGet.initializeProxy(); // https://github.com/electron/get#proxies
    const appPathArray = await (0, electron_packager_1.default)(options.packager);
    log.info('\nFinalizing build...');
    let appPath = getAppPath(appPathArray);
    if (!appPath) {
        throw new Error('App Path could not be determined.');
    }
    if (options.packager.upgrade &&
        options.packager.upgradeFrom &&
        options.packager.overwrite) {
        if (options.packager.platform === 'darwin') {
            try {
                // This is needed due to a funky thing that happens when copying Squirrel.framework
                // over where it gets into a circular file reference somehow.
                await fs.remove(path.join(finalOutDirectory, `${(_b = options.packager.name) !== null && _b !== void 0 ? _b : ''}.app`, 'Contents', 'Frameworks'));
            }
            catch (err) {
                log.warn('Encountered an error when attempting to pre-delete old frameworks:', err);
            }
            await fs.copy(path.join(appPath, `${(_c = options.packager.name) !== null && _c !== void 0 ? _c : ''}.app`), path.join(finalOutDirectory, `${(_d = options.packager.name) !== null && _d !== void 0 ? _d : ''}.app`), {
                overwrite: options.packager.overwrite,
                preserveTimestamps: true,
            });
        }
        else {
            await fs.copy(appPath, finalOutDirectory, {
                overwrite: options.packager.overwrite,
                preserveTimestamps: true,
            });
        }
        await fs.remove(appPath);
        appPath = finalOutDirectory;
    }
    const osRunHelp = getOSRunHelp(options.packager.platform);
    log.info(`App built to ${appPath}, move to wherever it makes sense for you and run ${osRunHelp}`);
    return appPath;
}
exports.buildNativefierApp = buildNativefierApp;
//# sourceMappingURL=buildNativefierApp.js.map