"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 });
const path_1 = __importDefault(require("path"));
const core_utils_1 = require("@electron-forge/core-utils");
const template_base_1 = __importDefault(require("@electron-forge/template-base"));
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 lodash_1 = require("lodash");
const install_dependencies_1 = __importStar(require("../util/install-dependencies"));
const read_package_json_1 = require("../util/read-package-json");
const upgrade_forge_config_1 = __importStar(require("../util/upgrade-forge-config"));
const init_git_1 = require("./init-scripts/init-git");
const init_npm_1 = require("./init-scripts/init-npm");
const d = (0, debug_1.default)('electron-forge:import');
exports.default = (0, tracer_1.autoTrace)({ name: 'import()', category: '@electron-forge/core' }, async (childTrace, { dir = process.cwd(), interactive = false, confirmImport, shouldContinueOnExisting, shouldRemoveDependency, shouldUpdateScript, outDir }) => {
    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: 'Locating importable project',
            task: childTrace({ name: 'locate-project', category: '@electron-forge/core' }, async () => {
                d(`Attempting to import project in: ${dir}`);
                if (!(await fs_extra_1.default.pathExists(dir)) || !(await fs_extra_1.default.pathExists(path_1.default.resolve(dir, 'package.json')))) {
                    throw new Error(`We couldn't find a project with a package.json file in: ${dir}`);
                }
                if (typeof confirmImport === 'function') {
                    if (!(await confirmImport())) {
                        // TODO: figure out if we can just return early here
                        // eslint-disable-next-line no-process-exit
                        process.exit(0);
                    }
                }
                await (0, init_git_1.initGit)(dir);
            }),
        },
        {
            title: 'Processing configuration and dependencies',
            rendererOptions: {
                persistentOutput: true,
                bottomBar: Infinity,
            },
            task: childTrace({ name: 'string', category: 'foo' }, async (_, ctx, task) => {
                const calculatedOutDir = outDir || 'out';
                const importDeps = [].concat(init_npm_1.deps);
                let importDevDeps = [].concat(init_npm_1.devDeps);
                let importExactDevDeps = [].concat(init_npm_1.exactDevDeps);
                let packageJSON = await (0, read_package_json_1.readRawPackageJson)(dir);
                if (!packageJSON.version) {
                    task.output = chalk_1.default.yellow(`Please set the ${chalk_1.default.green('"version"')} in your application's package.json`);
                }
                if (packageJSON.config && packageJSON.config.forge) {
                    if (packageJSON.config.forge.makers) {
                        task.output = chalk_1.default.green('Existing Electron Forge configuration detected');
                        if (typeof shouldContinueOnExisting === 'function') {
                            if (!(await shouldContinueOnExisting())) {
                                // TODO: figure out if we can just return early here
                                // eslint-disable-next-line no-process-exit
                                process.exit(0);
                            }
                        }
                    }
                    else if (!(typeof packageJSON.config.forge === 'object')) {
                        task.output = chalk_1.default.yellow("We can't tell if the Electron Forge config is compatible because it's in an external JavaScript file, not trying to convert it and continuing anyway");
                    }
                    else {
                        d('Upgrading an Electron Forge < 6 project');
                        packageJSON.config.forge = (0, upgrade_forge_config_1.default)(packageJSON.config.forge);
                        importDevDeps = (0, upgrade_forge_config_1.updateUpgradedForgeDevDeps)(packageJSON, importDevDeps);
                    }
                }
                packageJSON.dependencies = packageJSON.dependencies || {};
                packageJSON.devDependencies = packageJSON.devDependencies || {};
                [importDevDeps, importExactDevDeps] = (0, core_utils_1.updateElectronDependency)(packageJSON, importDevDeps, importExactDevDeps);
                const keys = Object.keys(packageJSON.dependencies).concat(Object.keys(packageJSON.devDependencies));
                const buildToolPackages = {
                    '@electron/get': 'already uses this module as a transitive dependency',
                    '@electron/osx-sign': 'already uses this module as a transitive dependency',
                    '@electron/packager': 'already uses this module as a transitive dependency',
                    'electron-builder': 'provides mostly equivalent functionality',
                    'electron-download': 'already uses this module as a transitive dependency',
                    'electron-forge': 'replaced with @electron-forge/cli',
                    'electron-installer-debian': 'already uses this module as a transitive dependency',
                    'electron-installer-dmg': 'already uses this module as a transitive dependency',
                    'electron-installer-flatpak': 'already uses this module as a transitive dependency',
                    'electron-installer-redhat': 'already uses this module as a transitive dependency',
                    'electron-winstaller': 'already uses this module as a transitive dependency',
                };
                for (const key of keys) {
                    if (buildToolPackages[key]) {
                        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                        const explanation = buildToolPackages[key];
                        let remove = true;
                        if (typeof shouldRemoveDependency === 'function') {
                            remove = await shouldRemoveDependency(key, explanation);
                        }
                        if (remove) {
                            delete packageJSON.dependencies[key];
                            delete packageJSON.devDependencies[key];
                        }
                    }
                }
                packageJSON.scripts = packageJSON.scripts || {};
                d('reading current scripts object:', packageJSON.scripts);
                const updatePackageScript = async (scriptName, newValue) => {
                    if (packageJSON.scripts[scriptName] !== newValue) {
                        let update = true;
                        if (typeof shouldUpdateScript === 'function') {
                            update = await shouldUpdateScript(scriptName, newValue);
                        }
                        if (update) {
                            packageJSON.scripts[scriptName] = newValue;
                        }
                    }
                };
                await updatePackageScript('start', 'electron-forge start');
                await updatePackageScript('package', 'electron-forge package');
                await updatePackageScript('make', 'electron-forge make');
                d('forgified scripts object:', packageJSON.scripts);
                const writeChanges = async () => {
                    await fs_extra_1.default.writeJson(path_1.default.resolve(dir, 'package.json'), packageJSON, { spaces: 2 });
                };
                return task.newListr([
                    {
                        title: 'Installing dependencies',
                        task: async (_, task) => {
                            const packageManager = (0, core_utils_1.safeYarnOrNpm)();
                            await writeChanges();
                            d('deleting old dependencies forcefully');
                            await fs_extra_1.default.remove(path_1.default.resolve(dir, 'node_modules/.bin/electron'));
                            await fs_extra_1.default.remove(path_1.default.resolve(dir, 'node_modules/.bin/electron.cmd'));
                            d('installing dependencies');
                            task.output = `${packageManager} install ${importDeps.join(' ')}`;
                            await (0, install_dependencies_1.default)(dir, importDeps);
                            d('installing devDependencies');
                            task.output = `${packageManager} install --dev ${importDevDeps.join(' ')}`;
                            await (0, install_dependencies_1.default)(dir, importDevDeps, install_dependencies_1.DepType.DEV);
                            d('installing exactDevDependencies');
                            task.output = `${packageManager} install --dev --exact ${importExactDevDeps.join(' ')}`;
                            await (0, install_dependencies_1.default)(dir, importExactDevDeps, install_dependencies_1.DepType.DEV, install_dependencies_1.DepVersionRestriction.EXACT);
                        },
                    },
                    {
                        title: 'Copying base template Forge configuration',
                        task: async () => {
                            const pathToTemplateConfig = path_1.default.resolve(template_base_1.default.templateDir, 'forge.config.js');
                            // if there's an existing config.forge object in package.json
                            if (packageJSON?.config?.forge && typeof packageJSON.config.forge === 'object') {
                                d('detected existing Forge config in package.json, merging with base template Forge config');
                                // eslint-disable-next-line @typescript-eslint/no-var-requires
                                const templateConfig = require(path_1.default.resolve(template_base_1.default.templateDir, 'forge.config.js'));
                                packageJSON = await (0, read_package_json_1.readRawPackageJson)(dir);
                                (0, lodash_1.merge)(templateConfig, packageJSON.config.forge); // mutates the templateConfig object
                                await writeChanges();
                                // otherwise, write to forge.config.js
                            }
                            else {
                                d('writing new forge.config.js');
                                await fs_extra_1.default.copyFile(pathToTemplateConfig, path_1.default.resolve(dir, 'forge.config.js'));
                            }
                        },
                    },
                    {
                        title: 'Fixing .gitignore',
                        task: async () => {
                            if (await fs_extra_1.default.pathExists(path_1.default.resolve(dir, '.gitignore'))) {
                                const gitignore = await fs_extra_1.default.readFile(path_1.default.resolve(dir, '.gitignore'));
                                if (!gitignore.includes(calculatedOutDir)) {
                                    await fs_extra_1.default.writeFile(path_1.default.resolve(dir, '.gitignore'), `${gitignore}\n${calculatedOutDir}/`);
                                }
                            }
                        },
                    },
                ], listrOptions);
            }),
        },
        {
            title: 'Finalizing import',
            rendererOptions: {
                persistentOutput: true,
                bottomBar: Infinity,
            },
            task: childTrace({ name: 'finalize-import', category: '@electron-forge/core' }, (_, __, task) => {
                task.output = `We have attempted to convert your app to be in a format that Electron Forge understands.
          
          Thanks for using ${chalk_1.default.green('Electron Forge')}!`;
            }),
        },
    ], listrOptions);
    await runner.run();
});
//# sourceMappingURL=data:application/json;base64, 