/**
 * Project Detector for Lazy Plugin Loading
 *
 * Analyzes project files to detect the project type and suggest relevant plugins.
 * Used by session-start hook for proactive plugin pre-loading.
 *
 * Detection is fast (<1 second) using file existence checks only.
 *
 * @module core/lazy-loading/project-detector
 */
import { existsSync, readFileSync } from 'fs';
import { join } from 'path';
/**
 * Helper to check if a file exists
 */
function fileExists(projectPath, filePath) {
    return existsSync(join(projectPath, filePath));
}
/**
 * Helper to check if a directory exists
 */
function dirExists(projectPath, dirPath) {
    return existsSync(join(projectPath, dirPath));
}
/**
 * Helper to check if package.json has a dependency
 */
function packageJsonHas(projectPath, dependency) {
    const packageJsonPath = join(projectPath, 'package.json');
    if (!existsSync(packageJsonPath))
        return false;
    try {
        const content = readFileSync(packageJsonPath, 'utf8');
        const pkg = JSON.parse(content);
        const deps = {
            ...pkg.dependencies,
            ...pkg.devDependencies,
            ...pkg.peerDependencies,
        };
        return dependency in deps;
    }
    catch {
        return false;
    }
}
/**
 * Helper to check if a file contains a string (fast search)
 */
function fileContains(projectPath, filePath, searchString) {
    const fullPath = join(projectPath, filePath);
    if (!existsSync(fullPath))
        return false;
    try {
        const content = readFileSync(fullPath, 'utf8');
        return content.toLowerCase().includes(searchString.toLowerCase());
    }
    catch {
        return false;
    }
}
/**
 * Project type detection rules
 * Ordered by specificity (more specific first)
 */
const DETECTION_RULES = [
    // Frontend frameworks
    {
        type: 'nextjs',
        plugins: ['backend'],
        detect: (p) => packageJsonHas(p, 'next') || fileExists(p, 'next.config.js') || fileExists(p, 'next.config.mjs') || fileExists(p, 'next.config.ts'),
    },
    {
        type: 'nuxt',
        plugins: ['backend'],
        detect: (p) => packageJsonHas(p, 'nuxt') || fileExists(p, 'nuxt.config.js') || fileExists(p, 'nuxt.config.ts'),
    },
    {
        type: 'react',
        plugins: [],
        detect: (p) => packageJsonHas(p, 'react') || fileExists(p, 'src/App.tsx') || fileExists(p, 'src/App.jsx'),
    },
    {
        type: 'vue',
        plugins: [],
        detect: (p) => packageJsonHas(p, 'vue') || fileExists(p, 'src/App.vue'),
    },
    {
        type: 'angular',
        plugins: [],
        detect: (p) => packageJsonHas(p, '@angular/core') || fileExists(p, 'angular.json'),
    },
    {
        type: 'svelte',
        plugins: [],
        detect: (p) => packageJsonHas(p, 'svelte') || fileExists(p, 'svelte.config.js'),
    },
    // Backend frameworks - Node.js
    {
        type: 'nestjs',
        plugins: ['backend'],
        detect: (p) => packageJsonHas(p, '@nestjs/core') || fileExists(p, 'nest-cli.json'),
    },
    {
        type: 'express',
        plugins: ['backend'],
        detect: (p) => packageJsonHas(p, 'express'),
    },
    {
        type: 'fastify',
        plugins: ['backend'],
        detect: (p) => packageJsonHas(p, 'fastify'),
    },
    // Backend frameworks - Python
    {
        type: 'fastapi',
        plugins: ['backend'],
        detect: (p) => fileContains(p, 'requirements.txt', 'fastapi') ||
            fileContains(p, 'pyproject.toml', 'fastapi'),
    },
    {
        type: 'django',
        plugins: ['backend'],
        detect: (p) => fileExists(p, 'manage.py') ||
            fileContains(p, 'requirements.txt', 'django') ||
            fileContains(p, 'pyproject.toml', 'django'),
    },
    {
        type: 'flask',
        plugins: ['backend'],
        detect: (p) => fileContains(p, 'requirements.txt', 'flask') ||
            fileContains(p, 'pyproject.toml', 'flask'),
    },
    // Backend frameworks - Go
    {
        type: 'go',
        plugins: ['backend'],
        detect: (p) => fileExists(p, 'go.mod'),
    },
    // Backend frameworks - Rust
    {
        type: 'rust',
        plugins: ['backend'],
        detect: (p) => fileExists(p, 'Cargo.toml'),
    },
    // Backend frameworks - Java/Kotlin
    {
        type: 'spring',
        plugins: ['backend'],
        detect: (p) => fileContains(p, 'pom.xml', 'spring-boot') ||
            fileContains(p, 'build.gradle', 'spring-boot') ||
            fileContains(p, 'build.gradle.kts', 'spring-boot'),
    },
    // Infrastructure
    {
        type: 'kubernetes',
        plugins: ['k8s', 'infra'],
        detect: (p) => dirExists(p, 'k8s') ||
            dirExists(p, 'kubernetes') ||
            dirExists(p, 'helm') ||
            fileExists(p, 'Chart.yaml') ||
            fileExists(p, 'kustomization.yaml'),
    },
    {
        type: 'docker',
        plugins: ['infra'],
        detect: (p) => fileExists(p, 'Dockerfile') ||
            fileExists(p, 'docker-compose.yml') ||
            fileExists(p, 'docker-compose.yaml') ||
            fileExists(p, 'compose.yml') ||
            fileExists(p, 'compose.yaml'),
    },
    {
        type: 'terraform',
        plugins: ['infra'],
        detect: (p) => fileExists(p, 'main.tf') ||
            fileExists(p, 'terraform.tf') ||
            dirExists(p, 'terraform'),
    },
    {
        type: 'pulumi',
        plugins: ['infra'],
        detect: (p) => fileExists(p, 'Pulumi.yaml'),
    },
    // Integrations
    {
        type: 'github',
        plugins: ['github'],
        detect: (p) => dirExists(p, '.github'),
    },
    {
        type: 'jira',
        plugins: ['jira'],
        detect: (p) => {
            const configPath = join(p, '.specweave', 'config.json');
            if (!existsSync(configPath))
                return false;
            try {
                const config = JSON.parse(readFileSync(configPath, 'utf8'));
                return config?.sync?.jira?.enabled === true;
            }
            catch {
                return false;
            }
        },
    },
    {
        type: 'ado',
        plugins: ['ado'],
        detect: (p) => {
            const configPath = join(p, '.specweave', 'config.json');
            if (!existsSync(configPath))
                return false;
            try {
                const config = JSON.parse(readFileSync(configPath, 'utf8'));
                return config?.sync?.ado?.enabled === true;
            }
            catch {
                return false;
            }
        },
    },
    // Mobile — vskill plugin recommendation (v1.0.542)
    {
        type: 'react-native',
        plugins: [],
        vskillPlugins: ['mobile'],
        detect: (p) => packageJsonHas(p, 'react-native') || fileExists(p, 'metro.config.js'),
    },
    {
        type: 'expo',
        plugins: [],
        vskillPlugins: ['mobile'],
        detect: (p) => packageJsonHas(p, 'expo'),
    },
    {
        type: 'ios',
        plugins: [],
        vskillPlugins: ['mobile'],
        detect: (p) => dirExists(p, 'ios') || fileExists(p, 'Podfile'),
    },
    {
        type: 'android',
        plugins: [],
        vskillPlugins: ['mobile'],
        detect: (p) => dirExists(p, 'android') ||
            fileContains(p, 'build.gradle', 'com.android') ||
            fileContains(p, 'build.gradle.kts', 'com.android'),
    },
    // ML/AI
    {
        type: 'pytorch',
        plugins: ['ml'],
        detect: (p) => fileContains(p, 'requirements.txt', 'torch') ||
            fileContains(p, 'pyproject.toml', 'torch'),
    },
    {
        type: 'tensorflow',
        plugins: ['ml'],
        detect: (p) => fileContains(p, 'requirements.txt', 'tensorflow') ||
            fileContains(p, 'pyproject.toml', 'tensorflow'),
    },
    // Messaging
    {
        type: 'kafka',
        plugins: ['kafka'],
        detect: (p) => packageJsonHas(p, 'kafkajs') ||
            fileContains(p, 'requirements.txt', 'kafka') ||
            fileContains(p, 'docker-compose.yml', 'kafka'),
    },
    // Testing
    {
        type: 'playwright',
        plugins: ['testing'],
        detect: (p) => packageJsonHas(p, '@playwright/test') || fileExists(p, 'playwright.config.ts'),
    },
    {
        type: 'cypress',
        plugins: ['testing'],
        detect: (p) => packageJsonHas(p, 'cypress') || dirExists(p, 'cypress'),
    },
    {
        type: 'vitest',
        plugins: ['testing'],
        detect: (p) => packageJsonHas(p, 'vitest') || fileExists(p, 'vitest.config.ts'),
    },
    {
        type: 'jest',
        plugins: ['testing'],
        detect: (p) => packageJsonHas(p, 'jest') || fileExists(p, 'jest.config.js'),
    },
    // Payments
    {
        type: 'stripe',
        plugins: ['payments'],
        detect: (p) => packageJsonHas(p, 'stripe') || fileContains(p, 'requirements.txt', 'stripe'),
    },
];
/**
 * Detects project types based on files in the project directory
 *
 * @param projectPath - Path to the project root directory
 * @returns Detection result with types and recommended plugins
 *
 * @example
 * ```ts
 * const result = detectProjectType('/path/to/react-app');
 * // { types: ['react', 'github'], plugins: ['github'] }
 * ```
 */
export function detectProjectType(projectPath = process.cwd()) {
    const startTime = performance.now();
    const detectedTypes = [];
    const detectedPlugins = new Set();
    const detectedVskillPlugins = new Set();
    // Run all detection rules
    for (const rule of DETECTION_RULES) {
        try {
            if (rule.detect(projectPath)) {
                detectedTypes.push(rule.type);
                rule.plugins.forEach((p) => detectedPlugins.add(p));
                if (rule.vskillPlugins) {
                    rule.vskillPlugins.forEach((p) => detectedVskillPlugins.add(p));
                }
            }
        }
        catch {
            // Ignore detection errors
        }
    }
    const result = {
        types: detectedTypes,
        plugins: Array.from(detectedPlugins),
        latencyMs: performance.now() - startTime,
    };
    if (detectedVskillPlugins.size > 0) {
        result.vskillPlugins = Array.from(detectedVskillPlugins);
    }
    return result;
}
/**
 * Gets recommended plugins for a list of project types
 *
 * @param types - Array of project type identifiers
 * @returns Array of recommended plugin names
 */
export function getRecommendedPlugins(types) {
    const plugins = new Set();
    for (const type of types) {
        const rule = DETECTION_RULES.find((r) => r.type === type);
        if (rule) {
            rule.plugins.forEach((p) => plugins.add(p));
        }
    }
    return Array.from(plugins);
}
/**
 * Gets all available detection rules (for testing/debugging)
 */
export function getDetectionRules() {
    return DETECTION_RULES.map((r) => ({ type: r.type, plugins: r.plugins }));
}
//# sourceMappingURL=project-detector.js.map