"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.rebase = void 0;
const chalk_1 = __importDefault(require("chalk"));
const path_1 = require("path");
const applyPatches_1 = require("./applyPatches");
const hash_1 = require("./hash");
const patchFs_1 = require("./patchFs");
const stateFile_1 = require("./stateFile");
function rebase({ appPath, patchDir, packagePathSpecifier, targetPatch, }) {
    const patchesDirectory = path_1.join(appPath, patchDir);
    const groupedPatches = patchFs_1.getGroupedPatches(patchesDirectory);
    if (groupedPatches.numPatchFiles === 0) {
        console.log(chalk_1.default.blueBright("No patch files found"));
        process.exit(1);
    }
    const packagePatches = groupedPatches.pathSpecifierToPatchFiles[packagePathSpecifier];
    if (!packagePatches) {
        console.log(chalk_1.default.blueBright("No patch files found for package"), packagePathSpecifier);
        process.exit(1);
    }
    const state = stateFile_1.getPatchApplicationState(packagePatches[0]);
    if (!state) {
        console.log(chalk_1.default.blueBright("No patch state found"), "Did you forget to run", chalk_1.default.bold("patch-package"), "(without arguments) first?");
        process.exit(1);
    }
    if (state.isRebasing) {
        console.log(chalk_1.default.blueBright("Already rebasing"), "Make changes to the files in", chalk_1.default.bold(packagePatches[0].path), "and then run `patch-package", packagePathSpecifier, "--continue` to", packagePatches.length === state.patches.length
            ? "append a patch file"
            : `update the ${packagePatches[packagePatches.length - 1].patchFilename} file`);
        console.log(`💡 To remove a broken patch file, delete it and reinstall node_modules`);
        process.exit(1);
    }
    if (state.patches.length !== packagePatches.length) {
        console.log(chalk_1.default.blueBright("Some patches have not been applied."), "Reinstall node_modules and try again.");
    }
    // check hashes
    stateFile_1.verifyAppliedPatches({ appPath, patchDir, state });
    if (targetPatch === "0") {
        // unapply all
        unApplyPatches({
            patches: packagePatches,
            appPath,
            patchDir,
        });
        stateFile_1.savePatchApplicationState({
            packageDetails: packagePatches[0],
            isRebasing: true,
            patches: [],
        });
        console.log(`
Make any changes you need inside ${chalk_1.default.bold(packagePatches[0].path)}

When you are done, run

  ${chalk_1.default.bold(`patch-package ${packagePathSpecifier} --append 'MyChangeDescription'`)}
  
to insert a new patch file.
`);
        return;
    }
    // find target patch
    const target = packagePatches.find((p) => {
        if (p.patchFilename === targetPatch) {
            return true;
        }
        if (path_1.resolve(process.cwd(), targetPatch) ===
            path_1.join(patchesDirectory, p.patchFilename)) {
            return true;
        }
        if (targetPatch === p.sequenceName) {
            return true;
        }
        const n = Number(targetPatch.replace(/^0+/g, ""));
        if (!isNaN(n) && n === p.sequenceNumber) {
            return true;
        }
        return false;
    });
    if (!target) {
        console.log(chalk_1.default.red("Could not find target patch file"), chalk_1.default.bold(targetPatch));
        console.log();
        console.log("The list of available patch files is:");
        packagePatches.forEach((p) => {
            console.log(`  - ${p.patchFilename}`);
        });
        process.exit(1);
    }
    const currentHash = hash_1.hashFile(path_1.join(patchesDirectory, target.patchFilename));
    const prevApplication = state.patches.find((p) => p.patchContentHash === currentHash);
    if (!prevApplication) {
        console.log(chalk_1.default.red("Could not find previous application of patch file"), chalk_1.default.bold(target.patchFilename));
        console.log();
        console.log("You should reinstall node_modules and try again.");
        process.exit(1);
    }
    // ok, we are good to start undoing all the patches that were applied up to but not including the target patch
    const targetIdx = state.patches.indexOf(prevApplication);
    unApplyPatches({
        patches: packagePatches.slice(targetIdx + 1),
        appPath,
        patchDir,
    });
    stateFile_1.savePatchApplicationState({
        packageDetails: packagePatches[0],
        isRebasing: true,
        patches: packagePatches.slice(0, targetIdx + 1).map((p) => ({
            patchFilename: p.patchFilename,
            patchContentHash: hash_1.hashFile(path_1.join(patchesDirectory, p.patchFilename)),
            didApply: true,
        })),
    });
    console.log(`
Make any changes you need inside ${chalk_1.default.bold(packagePatches[0].path)}

When you are done, do one of the following:

  To update ${chalk_1.default.bold(packagePatches[targetIdx].patchFilename)} run

    ${chalk_1.default.bold(`patch-package ${packagePathSpecifier}`)}
    
  To create a new patch file after ${chalk_1.default.bold(packagePatches[targetIdx].patchFilename)} run
  
    ${chalk_1.default.bold(`patch-package ${packagePathSpecifier} --append 'MyChangeDescription'`)}

  `);
}
exports.rebase = rebase;
function unApplyPatches({ patches, appPath, patchDir, }) {
    for (const patch of patches.slice().reverse()) {
        if (!applyPatches_1.applyPatch({
            patchFilePath: path_1.join(appPath, patchDir, patch.patchFilename),
            reverse: true,
            patchDetails: patch,
            patchDir,
            cwd: process.cwd(),
            bestEffort: false,
        })) {
            console.log(chalk_1.default.red("Failed to un-apply patch file"), chalk_1.default.bold(patch.patchFilename), "Try completely reinstalling node_modules.");
            process.exit(1);
        }
        console.log(chalk_1.default.cyan.bold("Un-applied"), patch.patchFilename);
    }
}
//# sourceMappingURL=data:application/json;base64,[encoded data, 14644 characters]