"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const tracer_1 = require("@electron-forge/tracer");
const chalk_1 = __importDefault(require("chalk"));
const debug_1 = __importDefault(require("debug"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const listr2_1 = require("listr2");
const forge_config_1 = __importDefault(require("../util/forge-config"));
const out_dir_1 = __importDefault(require("../util/out-dir"));
const publish_state_1 = __importDefault(require("../util/publish-state"));
const require_search_1 = __importDefault(require("../util/require-search"));
const resolve_dir_1 = __importDefault(require("../util/resolve-dir"));
const make_1 = require("./make");
const d = (0, debug_1.default)('electron-forge:publish');
exports.default = (0, tracer_1.autoTrace)({ name: 'publish()', category: '@electron-forge/core' }, async (childTrace, { dir: providedDir = process.cwd(), interactive = false, makeOptions = {}, publishTargets = undefined, dryRun = false, dryRunResume = false, outDir, }) => {
    if (dryRun && dryRunResume) {
        throw new Error("Can't dry run and resume a dry run at the same time");
    }
    const listrOptions = {
        concurrent: false,
        rendererOptions: {
            collapseErrors: false,
        },
        silentRendererCondition: !interactive,
        fallbackRendererCondition: Boolean(process.env.DEBUG) || Boolean(process.env.CI),
    };
    const publishDistributablesTasks = (childTrace) => [
        {
            title: 'Publishing distributables',
            task: childTrace({ name: 'publish-distributables', category: '@electron-forge/core' }, async (childTrace, { dir, forgeConfig, makeResults, publishers }, task) => {
                if (publishers.length === 0) {
                    task.output = 'No publishers configured';
                    task.skip();
                    return;
                }
                return (0, tracer_1.delayTraceTillSignal)(childTrace, task.newListr(publishers.map((publisher) => ({
                    title: `${chalk_1.default.cyan(`[publisher-${publisher.name}]`)} Running the ${chalk_1.default.yellow('publish')} command`,
                    task: childTrace({ name: `publish-${publisher.name}`, category: '@electron-forge/core' }, async (childTrace, _, task) => {
                        const setStatusLine = (s) => {
                            task.output = s;
                        };
                        await publisher.publish({
                            dir,
                            makeResults: makeResults,
                            forgeConfig,
                            setStatusLine,
                        });
                    }),
                    rendererOptions: {
                        persistentOutput: true,
                    },
                })), {
                    rendererOptions: {
                        collapseSubtasks: false,
                        collapseErrors: false,
                    },
                }), 'run');
            }),
            rendererOptions: {
                persistentOutput: true,
            },
        },
    ];
    const runner = new listr2_1.Listr([
        {
            title: 'Loading configuration',
            task: childTrace({ name: 'load-forge-config', category: '@electron-forge/core' }, async (childTrace, ctx) => {
                const resolvedDir = await (0, resolve_dir_1.default)(providedDir);
                if (!resolvedDir) {
                    throw new Error('Failed to locate publishable Electron application');
                }
                ctx.dir = resolvedDir;
                ctx.forgeConfig = await (0, forge_config_1.default)(resolvedDir);
            }),
        },
        {
            title: 'Resolving publish targets',
            task: childTrace({ name: 'resolve-publish-targets', category: '@electron-forge/core' }, async (childTrace, ctx, task) => {
                const { dir, forgeConfig } = ctx;
                if (!publishTargets) {
                    publishTargets = forgeConfig.publishers || [];
                }
                publishTargets = publishTargets.map((target) => {
                    if (typeof target === 'string') {
                        return ((forgeConfig.publishers || []).find((p) => {
                            if (typeof p === 'string')
                                return false;
                            if (p.__isElectronForgePublisher)
                                return false;
                            return p.name === target;
                        }) || { name: target });
                    }
                    return target;
                });
                ctx.publishers = [];
                for (const publishTarget of publishTargets) {
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    let publisher;
                    if (publishTarget.__isElectronForgePublisher) {
                        // eslint-disable-next-line @typescript-eslint/no-explicit-any
                        publisher = publishTarget;
                    }
                    else {
                        const resolvablePublishTarget = publishTarget;
                        // eslint-disable-next-line @typescript-eslint/no-explicit-any
                        const PublisherClass = (0, require_search_1.default)(dir, [resolvablePublishTarget.name]);
                        if (!PublisherClass) {
                            throw new Error(`Could not find a publish target with the name: ${resolvablePublishTarget.name}. Make sure it's listed in the devDependencies of your package.json`);
                        }
                        publisher = new PublisherClass(resolvablePublishTarget.config || {}, resolvablePublishTarget.platforms);
                    }
                    ctx.publishers.push(publisher);
                }
                if (ctx.publishers.length) {
                    task.output = `Publishing to the following targets: ${chalk_1.default.magenta(`${ctx.publishers.map((publisher) => publisher.name).join(', ')}`)}`;
                }
            }),
            rendererOptions: {
                persistentOutput: true,
            },
        },
        {
            title: dryRunResume ? 'Resuming from dry run...' : `Running ${chalk_1.default.yellow('make')} command`,
            task: childTrace({ name: dryRunResume ? 'resume-dry-run' : 'make()', category: '@electron-forge/core' }, async (childTrace, ctx, task) => {
                const { dir, forgeConfig } = ctx;
                const calculatedOutDir = outDir || (0, out_dir_1.default)(dir, forgeConfig);
                const dryRunDir = path_1.default.resolve(calculatedOutDir, 'publish-dry-run');
                if (dryRunResume) {
                    d('attempting to resume from dry run');
                    const publishes = await publish_state_1.default.loadFromDirectory(dryRunDir, dir);
                    task.title = `Resuming ${publishes.length} found dry runs...`;
                    return (0, tracer_1.delayTraceTillSignal)(childTrace, task.newListr(publishes.map((publishStates, index) => {
                        return {
                            title: `Publishing dry-run ${chalk_1.default.blue(`#${index + 1}`)}`,
                            task: childTrace({ name: `publish-dry-run-${index + 1}`, category: '@electron-forge/core' }, async (childTrace, ctx, task) => {
                                const restoredMakeResults = publishStates.map(({ state }) => state);
                                d('restoring publish settings from dry run');
                                for (const makeResult of restoredMakeResults) {
                                    makeResult.artifacts = await Promise.all(makeResult.artifacts.map(async (makePath) => {
                                        // standardize the path to artifacts across platforms
                                        const normalizedPath = makePath.split(/\/|\\/).join(path_1.default.sep);
                                        if (!(await fs_extra_1.default.pathExists(normalizedPath))) {
                                            throw new Error(`Attempted to resume a dry run, but an artifact (${normalizedPath}) could not be found`);
                                        }
                                        return normalizedPath;
                                    }));
                                }
                                d('publishing for given state set');
                                return (0, tracer_1.delayTraceTillSignal)(childTrace, task.newListr(publishDistributablesTasks(childTrace), {
                                    ctx: {
                                        ...ctx,
                                        makeResults: restoredMakeResults,
                                    },
                                    rendererOptions: {
                                        collapseSubtasks: false,
                                        collapseErrors: false,
                                    },
                                }), 'run');
                            }),
                        };
                    }), {
                        rendererOptions: {
                            collapseSubtasks: false,
                            collapseErrors: false,
                        },
                    }), 'run');
                }
                d('triggering make');
                return (0, tracer_1.delayTraceTillSignal)(childTrace, (0, make_1.listrMake)(childTrace, {
                    dir,
                    interactive,
                    ...makeOptions,
                }, (results) => {
                    ctx.makeResults = results;
                }), 'run');
            }),
        },
        ...(dryRunResume
            ? []
            : dryRun
                ? [
                    {
                        title: 'Saving dry-run state',
                        task: childTrace({ name: 'save-dry-run', category: '@electron-forge/core' }, async (childTrace, { dir, forgeConfig, makeResults }) => {
                            d('saving results of make in dry run state', makeResults);
                            const calculatedOutDir = outDir || (0, out_dir_1.default)(dir, forgeConfig);
                            const dryRunDir = path_1.default.resolve(calculatedOutDir, 'publish-dry-run');
                            await fs_extra_1.default.remove(dryRunDir);
                            await publish_state_1.default.saveToDirectory(dryRunDir, makeResults, dir);
                        }),
                    },
                ]
                : publishDistributablesTasks(childTrace)),
    ], listrOptions);
    await runner.run();
});
//# sourceMappingURL=data:application/json;base64, 