"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.tryUninstallPackage = exports.tryInstallPackage = exports.getPackageVersion = exports.canResolvePackage = exports.getPackageManager = exports.supports = exports.escapeRegExp = exports.getProjects = exports.getWorkspace = exports.getWorkspacePath = exports.getProjectPaths = void 0;
const core_1 = require("@angular-devkit/core");
const path = require("path");
const workspace_models_1 = require("@schematics/angular/utility/workspace-models");
const child_process_1 = require("child_process");
const configPaths = ['/.angular.json', '/angular.json'];
function getProjectPaths(config, appendPrefix = true) {
    const sourceDirs = [];
    let globalPrefix;
    if (config.schematics && config.schematics['@schematics/angular:component']) {
        // updated projects have global prefix rather than per-project:
        globalPrefix = config.schematics['@schematics/angular:component'].prefix;
    }
    const projects = getProjects(config);
    for (const proj of projects) {
        let sourcePath = path.join('/', proj.sourceRoot);
        if (appendPrefix && (proj.prefix || globalPrefix)) {
            sourcePath = path.join(sourcePath, proj.prefix || globalPrefix);
        }
        sourceDirs.push(core_1.normalize(sourcePath));
    }
    return sourceDirs;
}
exports.getProjectPaths = getProjectPaths;
function getWorkspacePath(host) {
    return configPaths.find(x => host.exists(x));
}
exports.getWorkspacePath = getWorkspacePath;
function getWorkspace(host) {
    const configPath = getWorkspacePath(host);
    if (configPath) {
        return JSON.parse(host.read(configPath).toString());
    }
    return null;
}
exports.getWorkspace = getWorkspace;
function getProjects(config) {
    const projects = [];
    for (const projName of Object.keys(config.projects)) {
        const proj = config.projects[projName];
        if ((proj.projectType && proj.projectType !== workspace_models_1.ProjectType.Application) ||
            (proj.architect && proj.architect.e2e && !proj.architect.build)) {
            continue;
        }
        projects.push(proj);
    }
    return projects;
}
exports.getProjects = getProjects;
function escapeRegExp(string) {
    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
exports.escapeRegExp = escapeRegExp;
function supports(name) {
    try {
        child_process_1.execSync(`${name} --version`, { stdio: 'ignore' });
        return true;
    }
    catch (_a) {
        return false;
    }
}
exports.supports = supports;
function getPackageManager(host) {
    const hasYarn = supports('yarn');
    const hasYarnLock = host.exists('yarn.lock');
    if (hasYarn && hasYarnLock) {
        return 'yarn';
    }
    return 'npm';
}
exports.getPackageManager = getPackageManager;
exports.canResolvePackage = (pkg) => {
    try {
        // attempt resolve in child process to keep result out of package.json cache
        // otherwise resolve will not read the json again (after install) and won't load the main correctly
        // https://stackoverflow.com/questions/59865584/how-to-invalidate-cached-require-resolve-results
        child_process_1.execSync(`node -e "require.resolve('${pkg}');"`, { stdio: 'ignore' });
        return true;
    }
    catch (_a) {
        return false;
    }
};
exports.getPackageVersion = (pkg) => {
    var _a;
    let version = null;
    try {
        version = (_a = require(path.posix.join(pkg, 'package.json'))) === null || _a === void 0 ? void 0 : _a.version;
    }
    catch (_b) { }
    return version;
};
function tryInstallPackage(context, packageManager, pkg) {
    try {
        context.logger.debug(`Installing ${pkg} via ${packageManager}.`);
        switch (packageManager) {
            case 'yarn':
                child_process_1.execSync(`${packageManager} add ${pkg} --no-lock-file`, { stdio: 'ignore' });
                break;
            case 'npm':
                child_process_1.execSync(`${packageManager} i ${pkg} --no-save`, { stdio: 'ignore' });
                break;
        }
        context.logger.debug(`${pkg} installed successfully.`);
    }
    catch (e) {
        context.logger.warn(`Could not install ${pkg}.`, JSON.parse(e));
    }
}
exports.tryInstallPackage = tryInstallPackage;
function tryUninstallPackage(context, packageManager, pkg) {
    try {
        context.logger.debug(`Uninstalling ${pkg} via ${packageManager}`);
        switch (packageManager) {
            case 'yarn':
                child_process_1.execSync(`${packageManager} remove ${pkg}`, { stdio: 'ignore' });
                break;
            case 'npm':
                child_process_1.execSync(`${packageManager} uninstall ${pkg} --no-save`, { stdio: 'ignore' });
                break;
        }
        context.logger.debug(`${pkg} uninstalled successfully.`);
    }
    catch (e) {
        context.logger
            .warn(`Could not uninstall ${pkg}, you may want to uninstall it manually.`, JSON.parse(e));
    }
}
exports.tryUninstallPackage = tryUninstallPackage;
