"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.listrMake = void 0;
const path_1 = __importDefault(require("path"));
const core_utils_1 = require("@electron-forge/core-utils");
const maker_base_1 = require("@electron-forge/maker-base");
const tracer_1 = require("@electron-forge/tracer");
const get_1 = require("@electron/get");
const chalk_1 = __importDefault(require("chalk"));
const filenamify_1 = __importDefault(require("filenamify"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const listr2_1 = require("listr2");
const log_symbols_1 = __importDefault(require("log-symbols"));
const forge_config_1 = __importDefault(require("../util/forge-config"));
const hook_1 = require("../util/hook");
const out_dir_1 = __importDefault(require("../util/out-dir"));
const parse_archs_1 = __importDefault(require("../util/parse-archs"));
const read_package_json_1 = require("../util/read-package-json");
const require_search_1 = __importDefault(require("../util/require-search"));
const resolve_dir_1 = __importDefault(require("../util/resolve-dir"));
const package_1 = require("./package");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
class MakerImpl extends maker_base_1.MakerBase {
    constructor() {
        super(...arguments);
        this.name = 'impl';
        this.defaultPlatforms = [];
    }
}
function generateTargets(forgeConfig, overrideTargets) {
    if (overrideTargets) {
        return overrideTargets.map((target) => {
            if (typeof target === 'string') {
                return forgeConfig.makers.find((maker) => maker.name === target) || { name: target };
            }
            return target;
        });
    }
    return forgeConfig.makers;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isElectronForgeMaker(target) {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return target.__isElectronForgeMaker;
}
const listrMake = (childTrace, { dir: providedDir = process.cwd(), interactive = false, skipPackage = false, arch = (0, get_1.getHostArch)(), platform = process.platform, overrideTargets, outDir, }, receiveMakeResults) => {
    const listrOptions = {
        concurrent: false,
        rendererOptions: {
            collapseSubtasks: false,
            collapseErrors: false,
        },
        silentRendererCondition: !interactive,
        fallbackRendererCondition: Boolean(process.env.DEBUG) || Boolean(process.env.CI),
    };
    const runner = new listr2_1.Listr([
        {
            title: 'Loading configuration',
            task: childTrace({ name: 'load-forge-config', category: '@electron-forge/core' }, async (_, ctx) => {
                const resolvedDir = await (0, resolve_dir_1.default)(providedDir);
                if (!resolvedDir) {
                    throw new Error('Failed to locate startable Electron application');
                }
                ctx.dir = resolvedDir;
                ctx.forgeConfig = await (0, forge_config_1.default)(resolvedDir);
            }),
        },
        {
            title: 'Resolving make targets',
            task: childTrace({ name: 'resolve-make-targets', category: '@electron-forge/core' }, async (_, ctx, task) => {
                const { dir, forgeConfig } = ctx;
                ctx.actualOutDir = outDir || (0, out_dir_1.default)(dir, forgeConfig);
                if (!['darwin', 'win32', 'linux', 'mas'].includes(platform)) {
                    throw new Error(`'${platform}' is an invalid platform. Choices are 'darwin', 'mas', 'win32' or 'linux'.`);
                }
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                const makers = [];
                const possibleMakers = generateTargets(forgeConfig, overrideTargets);
                for (const possibleMaker of possibleMakers) {
                    /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
                    let maker;
                    if (isElectronForgeMaker(possibleMaker)) {
                        maker = possibleMaker;
                        if (!maker.platforms.includes(platform))
                            continue;
                    }
                    else {
                        const resolvableTarget = possibleMaker;
                        // non-false falsy values should be 'true'
                        if (resolvableTarget.enabled === false)
                            continue;
                        if (!resolvableTarget.name) {
                            throw new Error(`The following maker config is missing a maker name: ${JSON.stringify(resolvableTarget)}`);
                        }
                        else if (typeof resolvableTarget.name !== 'string') {
                            throw new Error(`The following maker config has a maker name that is not a string: ${JSON.stringify(resolvableTarget)}`);
                        }
                        const MakerClass = (0, require_search_1.default)(dir, [resolvableTarget.name]);
                        if (!MakerClass) {
                            throw new Error(`Could not find module with name '${resolvableTarget.name}'. If this is a package from NPM, make sure it's listed in the devDependencies of your package.json. If this is a local module, make sure you have the correct path to its entry point. Try using the DEBUG="electron-forge:require-search" environment variable for more information.`);
                        }
                        maker = new MakerClass(resolvableTarget.config, resolvableTarget.platforms || undefined);
                        if (!maker.platforms.includes(platform))
                            continue;
                    }
                    if (!maker.isSupportedOnCurrentPlatform) {
                        throw new Error([
                            `Maker for target ${maker.name} is incompatible with this version of `,
                            'Electron Forge, please upgrade or contact the maintainer ',
                            "(needs to implement 'isSupportedOnCurrentPlatform)')",
                        ].join(''));
                    }
                    if (!maker.isSupportedOnCurrentPlatform()) {
                        throw new Error(`Cannot make for ${platform} and target ${maker.name}: the maker declared that it cannot run on ${process.platform}.`);
                    }
                    maker.ensureExternalBinariesExist();
                    makers.push(() => maker.clone());
                }
                if (makers.length === 0) {
                    throw new Error(`Could not find any make targets configured for the "${platform}" platform.`);
                }
                ctx.makers = makers;
                task.output = `Making for the following targets: ${chalk_1.default.magenta(`${makers.map((maker) => maker.name).join(', ')}`)}`;
            }),
            rendererOptions: {
                persistentOutput: true,
            },
        },
        {
            title: `Running ${chalk_1.default.yellow('package')} command`,
            task: childTrace({ name: 'package()', category: '@electron-forge/core' }, async (childTrace, ctx, task) => {
                if (!skipPackage) {
                    return (0, tracer_1.delayTraceTillSignal)(childTrace, (0, package_1.listrPackage)(childTrace, {
                        dir: ctx.dir,
                        interactive,
                        arch,
                        outDir: ctx.actualOutDir,
                        platform,
                    }), 'run');
                }
                else {
                    task.output = chalk_1.default.yellow(`${log_symbols_1.default.warning} Skipping could result in an out of date build`);
                    task.skip();
                }
            }),
            rendererOptions: {
                persistentOutput: true,
            },
        },
        {
            title: `Running ${chalk_1.default.yellow('preMake')} hook`,
            task: childTrace({ name: 'run-preMake-hook', category: '@electron-forge/core' }, async (childTrace, ctx, task) => {
                return (0, tracer_1.delayTraceTillSignal)(childTrace, task.newListr(await (0, hook_1.getHookListrTasks)(childTrace, ctx.forgeConfig, 'preMake')), 'run');
            }),
        },
        {
            title: 'Making distributables',
            task: childTrace({ name: 'make-distributables', category: '@electron-forge/core' }, async (childTrace, ctx, task) => {
                const { actualOutDir, dir, forgeConfig, makers } = ctx;
                const packageJSON = await (0, read_package_json_1.readMutatedPackageJson)(dir, forgeConfig);
                const appName = (0, filenamify_1.default)(forgeConfig.packagerConfig.name || packageJSON.productName || packageJSON.name, { replacement: '-' });
                const outputs = [];
                ctx.outputs = outputs;
                const subRunner = task.newListr([], {
                    ...listrOptions,
                    concurrent: true,
                    rendererOptions: {
                        collapseSubtasks: false,
                        collapseErrors: false,
                    },
                });
                for (const targetArch of (0, parse_archs_1.default)(platform, arch, await (0, core_utils_1.getElectronVersion)(dir, packageJSON))) {
                    const packageDir = path_1.default.resolve(actualOutDir, `${appName}-${platform}-${targetArch}`);
                    if (!(await fs_extra_1.default.pathExists(packageDir))) {
                        throw new Error(`Couldn't find packaged app at: ${packageDir}`);
                    }
                    for (const maker of makers) {
                        const uniqMaker = maker();
                        subRunner.add({
                            title: `Making a ${chalk_1.default.magenta(uniqMaker.name)} distributable for ${chalk_1.default.cyan(`${platform}/${targetArch}`)}`,
                            task: childTrace({ name: `make-${maker.name}`, category: '@electron-forge/core', newRoot: true }, async () => {
                                try {
                                    await Promise.resolve(uniqMaker.prepareConfig(targetArch));
                                    const artifacts = await uniqMaker.make({
                                        appName,
                                        forgeConfig,
                                        packageJSON,
                                        targetArch,
                                        dir: packageDir,
                                        makeDir: path_1.default.resolve(actualOutDir, 'make'),
                                        targetPlatform: platform,
                                    });
                                    outputs.push({
                                        artifacts,
                                        packageJSON,
                                        platform,
                                        arch: targetArch,
                                    });
                                }
                                catch (err) {
                                    if (err) {
                                        throw err;
                                    }
                                    else {
                                        throw new Error(`An unknown error occurred while making for target: ${uniqMaker.name}`);
                                    }
                                }
                            }),
                            rendererOptions: {
                                timer: { ...listr2_1.PRESET_TIMER },
                            },
                        });
                    }
                }
                return (0, tracer_1.delayTraceTillSignal)(childTrace, subRunner, 'run');
            }),
        },
        {
            title: `Running ${chalk_1.default.yellow('postMake')} hook`,
            task: childTrace({ name: 'run-postMake-hook', category: '@electron-forge/core' }, async (_, ctx, task) => {
                // If the postMake hooks modifies the locations / names of the outputs it must return
                // the new locations so that the publish step knows where to look
                ctx.outputs = await (0, hook_1.runMutatingHook)(ctx.forgeConfig, 'postMake', ctx.outputs);
                receiveMakeResults?.(ctx.outputs);
                task.output = `Artifacts available at: ${chalk_1.default.green(path_1.default.resolve(ctx.actualOutDir, 'make'))}`;
            }),
            rendererOptions: {
                persistentOutput: true,
            },
        },
    ], {
        ...listrOptions,
        ctx: {},
    });
    return runner;
};
exports.listrMake = listrMake;
exports.default = (0, tracer_1.autoTrace)({ name: 'make()', category: '@electron-forge/core' }, async (childTrace, opts) => {
    const runner = (0, exports.listrMake)(childTrace, opts);
    await runner.run();
    return runner.ctx.outputs;
});
//# sourceMappingURL=data:application/json;base64, 