/**
 * Package installer for Docusaurus dependencies
 * Handles npm install with progress tracking
 */
import * as path from 'path';
import * as fs from '../../utils/fs-native.js';
import { spawn } from 'child_process';
import { execFileNoThrow } from '../execFileNoThrow.js';
import { NPM_REGISTRY_URL } from '../npm-constants.js';
/**
 * Check Node.js version
 */
export async function checkNodeVersion() {
    try {
        const result = await execFileNoThrow('node', ['--version']);
        if (!result.success) {
            throw new Error('Node.js not found');
        }
        const versionString = result.stdout.trim().replace('v', '');
        const [major, minor, patch] = versionString.split('.').map(Number);
        return {
            version: versionString,
            major,
            minor,
            patch,
            compatible: major >= 18
        };
    }
    catch (error) {
        throw new Error('Node.js not found. Please install Node.js 18+ from https://nodejs.org/');
    }
}
/**
 * Check if npm is installed
 */
export async function checkNpmInstalled() {
    try {
        const result = await execFileNoThrow('npm', ['--version']);
        return result.success;
    }
    catch {
        return false;
    }
}
/**
 * Install npm packages
 *
 * IMPORTANT: Uses public npm registry to bypass private registry configurations.
 * This is critical for user projects that may have Azure DevOps/private registries configured.
 */
export async function installPackages(options) {
    const { targetDir, packages, dev = false } = options;
    // Ensure target directory exists
    await fs.ensureDir(targetDir);
    // Build npm install command
    // Use public npm registry to avoid authentication issues with private registries
    const args = [
        'install',
        `--registry=${NPM_REGISTRY_URL}`,
        '--legacy-peer-deps' // Handle React 19 peer dependency issues
    ];
    if (dev) {
        args.push('--save-dev');
    }
    args.push(...packages);
    // Spawn npm install process
    // Note: shell:true removed - npm works without shell on all platforms when called with array args
    // On Windows, npm.cmd is found automatically via PATH
    return new Promise((resolve, reject) => {
        const npmProcess = spawn('npm', args, {
            cwd: targetDir,
            stdio: ['ignore', 'pipe', 'pipe'],
            // Security: Using shell only on Windows where npm.cmd requires it
            shell: process.platform === 'win32'
        });
        let stdout = '';
        let stderr = '';
        npmProcess.stdout.on('data', (data) => {
            stdout += data.toString();
            // Show progress to console
            process.stdout.write('.');
        });
        npmProcess.stderr.on('data', (data) => {
            stderr += data.toString();
        });
        npmProcess.on('close', (code) => {
            if (code === 0) {
                console.log(' ✅');
                resolve();
            }
            else {
                console.log(' ❌');
                reject(new Error(`npm install failed with code ${code}\n${stderr}`));
            }
        });
        npmProcess.on('error', (error) => {
            reject(new Error(`Failed to start npm install: ${error.message}`));
        });
    });
}
/**
 * Install Docusaurus packages
 */
export async function installDocusaurus(targetDir) {
    // Use latest stable Docusaurus 3.x versions
    const packages = [
        '@docusaurus/core@^3.9.0',
        '@docusaurus/preset-classic@^3.9.0',
        '@docusaurus/theme-mermaid@^3.9.0',
        '@mdx-js/react@^3.0.0',
        'clsx@^2.0.0',
        'prism-react-renderer@^2.3.0',
        'react@^19.0.0',
        'react-dom@^19.0.0'
    ];
    const devPackages = [
        '@docusaurus/module-type-aliases@^3.9.0',
        '@docusaurus/types@^3.9.0'
    ];
    console.log('   Installing Docusaurus packages...');
    await installPackages({
        targetDir,
        packages,
        dev: false
    });
    console.log('   Installing dev dependencies...');
    await installPackages({
        targetDir,
        packages: devPackages,
        dev: true
    });
}
/**
 * Check if Docusaurus is installed
 */
export async function isDocusaurusInstalled(targetDir) {
    try {
        const packageJsonPath = path.join(targetDir, 'package.json');
        const nodeModulesPath = path.join(targetDir, 'node_modules');
        // Check if package.json exists
        if (!await fs.pathExists(packageJsonPath)) {
            return false;
        }
        // Check if node_modules exists
        if (!await fs.pathExists(nodeModulesPath)) {
            return false;
        }
        // Check if @docusaurus/core is installed
        const docusaurusCorePath = path.join(nodeModulesPath, '@docusaurus', 'core');
        if (!await fs.pathExists(docusaurusCorePath)) {
            return false;
        }
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Clean npm cache
 */
export async function cleanNpmCache() {
    await execFileNoThrow('npm', ['cache', 'clean', '--force']);
}
/**
 * Get installed npm package version
 */
export async function getPackageVersion(targetDir, packageName) {
    try {
        const packageJsonPath = path.join(targetDir, 'node_modules', packageName, 'package.json');
        if (!await fs.pathExists(packageJsonPath)) {
            return null;
        }
        const packageJson = await fs.readJSON(packageJsonPath);
        return packageJson.version || null;
    }
    catch {
        return null;
    }
}
/**
 * Estimate install size (rough estimate)
 */
export function estimateInstallSize() {
    // Docusaurus + React + dependencies ≈ 150-200 MB
    return '~150 MB';
}
/**
 * Estimate install time (rough estimate)
 */
export function estimateInstallTime() {
    // Typically 20-40 seconds depending on network and CPU
    return '~30 seconds';
}
//# sourceMappingURL=package-installer.js.map