"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.newLineSeparator = exports.fileSeparator = void 0;
exports.getGradleExecFile = getGradleExecFile;
exports.execGradleAsync = execGradleAsync;
exports.getCustomGradleExecutableDirectoryFromPlugin = getCustomGradleExecutableDirectoryFromPlugin;
exports.findGradlewFile = findGradlewFile;
exports.findGradlewUsingFilePathTraversal = findGradlewUsingFilePathTraversal;
exports.findGradlewUsingCustomExecutableDirectory = findGradlewUsingCustomExecutableDirectory;
const devkit_1 = require("@nx/devkit");
const node_child_process_1 = require("node:child_process");
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const run_commands_impl_1 = require("nx/src/executors/run-commands/run-commands.impl");
const exit_codes_1 = require("nx/src/utils/exit-codes");
exports.fileSeparator = process.platform.startsWith('win')
    ? 'file:///'
    : 'file://';
exports.newLineSeparator = process.platform.startsWith('win')
    ? '\r\n'
    : '\n';
/**
 * For gradle command, it needs to be run from the directory of the gradle binary
 * @returns gradle binary file name
 */
function getGradleExecFile() {
    return process.platform.startsWith('win') ? '.\\gradlew.bat' : './gradlew';
}
/**
 * This function executes gradle with the given arguments
 * @param gradleBinaryPath absolute path to gradle binary
 * @param args args passed to gradle
 * @param execOptions exec options
 * @returns promise with the stdout buffer
 */
function execGradleAsync(gradleBinaryPath, args, execOptions = {}) {
    return new Promise((res, rej) => {
        const cp = (0, node_child_process_1.execFile)(gradleBinaryPath, args, {
            cwd: (0, node_path_1.dirname)(gradleBinaryPath),
            shell: true,
            windowsHide: true,
            env: process.env,
            maxBuffer: run_commands_impl_1.LARGE_BUFFER,
            ...execOptions,
        }, undefined);
        let stdout = Buffer.from('');
        cp.stdout?.on('data', (data) => {
            stdout += data;
        });
        cp.stderr?.on('data', (data) => {
            stdout += data;
        });
        cp.on('exit', (code, signal) => {
            if (code === null)
                code = (0, exit_codes_1.signalToCode)(signal);
            if (code === 0) {
                res(stdout);
            }
            else {
                rej(stdout);
            }
        });
    });
}
function getCustomGradleExecutableDirectoryFromPlugin(nxJson) {
    const gradlePlugin = nxJson.plugins?.find((plugin) => {
        if (typeof plugin === 'string') {
            return plugin === '@nx/gradle';
        }
        return plugin.plugin === '@nx/gradle';
    });
    return gradlePlugin && typeof gradlePlugin !== 'string'
        ? gradlePlugin.options?.gradleExecutableDirectory
        : undefined;
}
/**
 * This function recursively finds the nearest gradlew file in the workspace
 * @param filePathToSearch the original file to search for, relative to workspace root, file path not directory path
 * @param workspaceRoot workspace root
 * @param customExecutableDirectory a custom directory to search for the gradle wrapper file
 * @returns the relative path of the gradlew file to workspace root, throws an error if gradlew file is not found
 * It will return relative path to workspace root of gradlew.bat file on windows and gradlew file on other platforms
 */
function findGradlewFile(filePathToSearch, workspaceRoot, customExecutableDirectory) {
    if (customExecutableDirectory) {
        return findGradlewUsingCustomExecutableDirectory(customExecutableDirectory, workspaceRoot);
    }
    return findGradlewUsingFilePathTraversal(filePathToSearch, workspaceRoot);
}
function findGradlewUsingFilePathTraversal(filePathToSearch, workspaceRoot, currentSearchPath) {
    currentSearchPath ??= filePathToSearch;
    const parent = (0, node_path_1.dirname)(currentSearchPath);
    if (currentSearchPath === parent) {
        throw new devkit_1.AggregateCreateNodesError([
            [
                filePathToSearch,
                new Error(`No Gradlew file found at ${filePathToSearch} or any of its parent directories. Run "gradle init"`),
            ],
        ], []);
    }
    const gradlewPath = (0, node_path_1.join)(parent, 'gradlew');
    const gradlewBatPath = (0, node_path_1.join)(parent, 'gradlew.bat');
    if (process.platform.startsWith('win')) {
        if ((0, node_fs_1.existsSync)((0, node_path_1.join)(workspaceRoot, gradlewBatPath))) {
            return gradlewBatPath;
        }
    }
    else {
        if ((0, node_fs_1.existsSync)((0, node_path_1.join)(workspaceRoot, gradlewPath))) {
            return gradlewPath;
        }
    }
    return findGradlewUsingFilePathTraversal(filePathToSearch, workspaceRoot, parent);
}
function findGradlewUsingCustomExecutableDirectory(customGradleExecutableDirectory, workspaceRoot) {
    // Resolve the custom installation path - if relative, resolve against workspace root
    const resolvedInstallationPath = (0, node_path_1.isAbsolute)(customGradleExecutableDirectory)
        ? customGradleExecutableDirectory
        : (0, node_path_1.join)(workspaceRoot, customGradleExecutableDirectory);
    const customGradlewPath = (0, node_path_1.join)(resolvedInstallationPath, 'gradlew');
    const customGradlewBatPath = (0, node_path_1.join)(resolvedInstallationPath, 'gradlew.bat');
    if (process.platform.startsWith('win')) {
        if ((0, node_fs_1.existsSync)(customGradlewBatPath)) {
            // Return path relative to workspace root if it was relative, otherwise return absolute
            return (0, node_path_1.isAbsolute)(customGradleExecutableDirectory)
                ? customGradlewBatPath
                : (0, node_path_1.join)(customGradleExecutableDirectory, 'gradlew.bat');
        }
    }
    else {
        if ((0, node_fs_1.existsSync)(customGradlewPath)) {
            // Return path relative to workspace root if it was relative, otherwise return absolute
            return (0, node_path_1.isAbsolute)(customGradleExecutableDirectory)
                ? customGradlewPath
                : (0, node_path_1.join)(customGradleExecutableDirectory, 'gradlew');
        }
    }
    throw new devkit_1.AggregateCreateNodesError([
        [
            customGradleExecutableDirectory,
            new Error(`No Gradlew file found at custom gradle executable directory. Please ensure that there is a gradle wrapper file located at ${customGradleExecutableDirectory}`),
        ],
    ], []);
}
