/**
 * LanguageAnalyzer - Analyzes project to recommend LSP servers
 *
 * Uses weighted scoring to identify the top languages in a project.
 * Project files (package.json, .sln, go.mod) score higher than source files.
 *
 * @see spec.md US-003: LSP Server Recommendations
 * @satisfies AC-US3-01, AC-US3-02
 */
/**
 * Supported language configurations
 */
const LANGUAGE_CONFIGS = [
    {
        language: 'typescript',
        projectPatterns: ['package.json', 'tsconfig.json'],
        sourcePatterns: ['.ts', '.tsx'],
    },
    {
        language: 'csharp',
        projectPatterns: ['.sln', '.csproj'],
        sourcePatterns: ['.cs'],
    },
    {
        language: 'python',
        projectPatterns: ['pyproject.toml', 'setup.py', 'requirements.txt'],
        sourcePatterns: ['.py'],
    },
    {
        language: 'go',
        projectPatterns: ['go.mod'],
        sourcePatterns: ['.go'],
    },
    {
        language: 'rust',
        projectPatterns: ['Cargo.toml'],
        sourcePatterns: ['.rs'],
    },
    {
        language: 'java',
        projectPatterns: ['pom.xml', 'build.gradle'],
        sourcePatterns: ['.java'],
    },
];
/** Score for project files */
const PROJECT_FILE_WEIGHT = 10;
/** Score for source files */
const SOURCE_FILE_WEIGHT = 1;
/** Maximum number of languages to return */
const MAX_LANGUAGES = 3;
/** Directories to ignore */
const IGNORED_DIRS = ['node_modules', 'dist', '.git', 'vendor', '__pycache__'];
/**
 * Analyzes a project to identify the primary programming languages
 */
export class LanguageAnalyzer {
    constructor(fs) {
        this.fs = fs;
    }
    /**
     * Analyze a project directory to identify languages
     *
     * @param projectRoot - Root directory of the project
     * @returns Promise resolving to sorted array of language scores (max 3)
     */
    async analyze(projectRoot) {
        const scores = [];
        for (const config of LANGUAGE_CONFIGS) {
            const score = await this.scoreLanguage(config, projectRoot);
            if (score.score > 0) {
                scores.push(score);
            }
        }
        // Sort by score descending and return top 3
        return scores.sort((a, b) => b.score - a.score).slice(0, MAX_LANGUAGES);
    }
    async scoreLanguage(config, projectRoot) {
        const projectFiles = [];
        const sourceFiles = [];
        let score = 0;
        // Check project files
        for (const pattern of config.projectPatterns) {
            const files = await this.findFiles(pattern, projectRoot);
            const filteredFiles = this.filterIgnoredDirs(files);
            projectFiles.push(...filteredFiles);
            score += filteredFiles.length * PROJECT_FILE_WEIGHT;
        }
        // Check source files
        for (const pattern of config.sourcePatterns) {
            const files = await this.findFiles(pattern, projectRoot);
            const filteredFiles = this.filterIgnoredDirs(files);
            sourceFiles.push(...filteredFiles);
            score += filteredFiles.length * SOURCE_FILE_WEIGHT;
        }
        return {
            language: config.language,
            score,
            projectFiles,
            sourceFiles,
        };
    }
    async findFiles(pattern, cwd) {
        // Convert extension pattern to glob
        const globPattern = pattern.startsWith('.') ? `**/*${pattern}` : `**/${pattern}`;
        return this.fs.glob(globPattern, cwd);
    }
    filterIgnoredDirs(files) {
        return files.filter((file) => {
            // Split by both forward and back slashes for cross-platform support
            const parts = file.split(/[/\\]/);
            for (const ignored of IGNORED_DIRS) {
                if (parts.includes(ignored)) {
                    return false;
                }
            }
            return true;
        });
    }
}
//# sourceMappingURL=language-analyzer.js.map