"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkPackageDependents = checkPackageDependents;
exports.formatDependentsError = formatDependentsError;
// packages/nx/src/generators/remove/remove-utils.ts
const devkit_1 = require("@nx/devkit");
/**
 * Recursively collect all file paths under a directory in the Tree.
 */
function collectFiles(tree, dir) {
    if (!tree.exists(dir))
        return [];
    const results = [];
    for (const child of tree.children(dir)) {
        const full = `${dir}/${child}`;
        if (tree.isFile(full)) {
            results.push(full);
        }
        else {
            results.push(...collectFiles(tree, full));
        }
    }
    return results;
}
/**
 * Resolve the path alias for a package from tsconfig.base.json.
 * Returns undefined if no matching entry found.
 */
function resolveAlias(tree, normalizedName) {
    if (!tree.exists('tsconfig.base.json'))
        return undefined;
    const tsconfig = (0, devkit_1.readJson)(tree, 'tsconfig.base.json');
    const paths = tsconfig?.compilerOptions?.paths ?? {};
    const suffix = `/${normalizedName}/src/index.ts`;
    for (const [alias, values] of Object.entries(paths)) {
        if (Array.isArray(values) && values.some((v) => v.endsWith(suffix))) {
            return alias;
        }
    }
    return undefined;
}
/**
 * Check all workspace members under unisphere/ for dependents of the given package.
 *
 * @param tree - Nx virtual file tree
 * @param normalizedName - Kebab-case package name (already normalized via names().fileName)
 */
function checkPackageDependents(tree, normalizedName) {
    const packageJsonDependents = [];
    const importDependents = [];
    // 1. Resolve alias
    const alias = resolveAlias(tree, normalizedName);
    if (!alias) {
        devkit_1.logger.warn(`Could not resolve path alias for package '${normalizedName}' in tsconfig.base.json — import scan skipped.`);
    }
    // Derive sourceRoot of the package being removed (to exclude its own files)
    const tsconfig = tree.exists('tsconfig.base.json')
        ? (0, devkit_1.readJson)(tree, 'tsconfig.base.json')
        : {};
    const paths = tsconfig?.compilerOptions?.paths ?? {};
    const suffix = `/${normalizedName}/src/index.ts`;
    let packageSourceRoot;
    for (const values of Object.values(paths)) {
        if (Array.isArray(values)) {
            const match = values.find((v) => v.endsWith(suffix));
            if (match) {
                packageSourceRoot = match.replace('/src/index.ts', '');
                break;
            }
        }
    }
    // 2. Walk all files under unisphere/
    const allFiles = collectFiles(tree, 'unisphere');
    const DEP_FIELDS = ['dependencies', 'devDependencies', 'peerDependencies'];
    for (const filePath of allFiles) {
        // Skip files within the package being removed
        if (packageSourceRoot && filePath.startsWith(packageSourceRoot + '/')) {
            continue;
        }
        // 2a. package.json scan
        if (filePath.endsWith('/package.json') || filePath === 'package.json') {
            if (!alias)
                continue;
            try {
                const pkg = (0, devkit_1.readJson)(tree, filePath);
                const dir = filePath.replace('/package.json', '');
                for (const field of DEP_FIELDS) {
                    if (pkg[field]?.[alias] !== undefined) {
                        packageJsonDependents.push({ path: dir, field });
                    }
                }
            }
            catch {
                // malformed package.json — skip
            }
            continue;
        }
        // 2b. TypeScript import scan
        if (alias && (filePath.endsWith('.ts') || filePath.endsWith('.tsx'))) {
            const content = tree.read(filePath, 'utf-8');
            if (content && content.includes(alias)) {
                importDependents.push(filePath);
            }
        }
    }
    return { packageJsonDependents, importDependents };
}
/**
 * Format a human-readable error listing all dependents.
 */
function formatDependentsError(packageName, packageJsonDependents, importDependents) {
    const lines = [
        `Cannot remove package "${packageName}" — it is still in use.`,
        '',
    ];
    if (packageJsonDependents.length > 0) {
        lines.push('package.json dependents:');
        for (const dep of packageJsonDependents) {
            lines.push(`  • ${dep.path} (${dep.field})`);
        }
        lines.push('');
    }
    if (importDependents.length > 0) {
        lines.push('Import dependents:');
        for (const file of importDependents) {
            lines.push(`  • ${file}`);
        }
        lines.push('');
    }
    lines.push('To force removal anyway, run with --forceRemove.');
    return lines.join('\n');
}
