// Planu — Code Analysis Engine
// Orchestrates project analysis by delegating to specialized detectors
import { fileExists, hasAnyFile, loadStackSignatures, loadArchPatterns, } from './detection-utils.js';
import { detectLanguage, detectLanguageVersion } from './language-detector.js';
import { detectFramework, detectFrameworkVersion, detectDatabase, detectOrm, detectPackageManager, detectBuildCommand, detectTestCommand, detectLintCommand, } from './framework-detector.js';
import { detectArchitecture } from './architecture-detector.js';
import { detectApps, isMonorepoProject, detectApiContracts } from './multi-app-detector.js';
import { detectProjectCategory } from './platform-detector.js';
import { analyzeEnvSetup, discoverMcps, buildStackList, buildQualityProfile, } from './analyzer-env.js';
import { detectAgentProjectKnowledge } from './detectors/agent-framework-detector.js';
import { analyzeLinting, detectConventions, detectEnvironments, detectExternalServices, detectTooling, } from './analyzer-detectors.js';
// === Public API ===
/**
 * Full project analysis: scans filesystem to build ProjectKnowledge.
 */
export async function analyzeProject(projectPath, projectId, locale = 'en', experienceLevel = 'intermediate', stackSignatures, archPatterns) {
    const signatures = stackSignatures ?? (await loadStackSignatures());
    const archConfig = archPatterns ?? (await loadArchPatterns());
    const [language, framework, packageManager, database, orm, apps, architecture, linting, envSetup, apiContracts, mcps, conventions, monorepo, _completeness,] = await Promise.all([
        detectLanguage(projectPath, signatures),
        detectFramework(projectPath, signatures),
        detectPackageManager(projectPath, signatures),
        detectDatabase(projectPath, signatures),
        detectOrm(projectPath),
        detectApps(projectPath, signatures, archConfig),
        detectArchitecture(projectPath, archConfig),
        analyzeLinting(projectPath),
        analyzeEnvSetup(projectPath, projectId),
        detectApiContracts(projectPath),
        discoverMcps(projectPath),
        detectConventions(projectPath),
        isMonorepoProject(projectPath),
        checkProjectCompleteness(projectPath),
    ]);
    const [languageVersion, frameworkVersion, buildCommand, testCommand, lintCommand, externalServices, tooling, environments, projectCategory, agentKnowledge,] = await Promise.all([
        detectLanguageVersion(projectPath, language),
        detectFrameworkVersion(projectPath, framework, signatures),
        detectBuildCommand(projectPath, packageManager),
        detectTestCommand(projectPath, packageManager),
        detectLintCommand(projectPath, packageManager),
        detectExternalServices(projectPath),
        detectTooling(projectPath),
        detectEnvironments(projectPath),
        detectProjectCategory(projectPath, framework),
        detectAgentProjectKnowledge(projectPath),
    ]);
    const stack = buildStackList(language, framework, database, packageManager);
    const layers = architecture.layers.map((l) => l.name);
    const qualityProfile = buildQualityProfile(linting, conventions);
    return {
        projectId,
        projectPath,
        locale,
        experienceLevel,
        language,
        languageVersion,
        framework,
        frameworkVersion,
        packageManager,
        buildCommand,
        testCommand,
        lintCommand,
        stack,
        database,
        orm,
        architecture,
        apps,
        conventions,
        layers,
        environments,
        apiContracts,
        monorepo,
        externalServices,
        tooling,
        specLocation: 'planu/specs',
        envSetup,
        linting,
        availableMcps: mcps,
        docsRegistry: {},
        qualityProfile,
        lastAnalyzed: new Date().toISOString(),
        projectCategory,
        agentKnowledge: agentKnowledge.framework !== null ? agentKnowledge : undefined,
    };
}
/**
 * Quick analysis: only detects language, framework, and package manager.
 */
export async function quickAnalyze(projectPath) {
    const signatures = await loadStackSignatures();
    const [language, framework, packageManager, database] = await Promise.all([
        detectLanguage(projectPath, signatures),
        detectFramework(projectPath, signatures),
        detectPackageManager(projectPath, signatures),
        detectDatabase(projectPath, signatures),
    ]);
    return { language, framework, packageManager, database };
}
/**
 * Check project completeness (has readme, gitignore, tests, ci, etc.)
 */
export async function checkProjectCompleteness(projectPath) {
    const checks = await Promise.all([
        fileExists(projectPath, 'README.md'),
        fileExists(projectPath, '.gitignore'),
        fileExists(projectPath, '.env.example').then((r) => r || fileExists(projectPath, '.env.local.example')),
        fileExists(projectPath, 'LICENSE'),
        fileExists(projectPath, '.editorconfig'),
        hasAnyFile(projectPath, [
            '.eslintrc*',
            'eslint.config.*',
            'biome.json',
            '.pylintrc',
            'ruff.toml',
            '.golangci.yml',
            'Cargo.toml',
        ]),
        hasAnyFile(projectPath, ['.prettierrc*', 'biome.json', '.editorconfig']),
        hasAnyFile(projectPath, [
            'jest.config.*',
            'vitest.config.*',
            'pytest.ini',
            'pyproject.toml',
            'Cargo.toml',
            '*.test.*',
            '*.spec.*',
        ]),
        hasAnyFile(projectPath, [
            '.github/workflows/*',
            '.gitlab-ci.yml',
            'Jenkinsfile',
            '.circleci/config.yml',
        ]),
        hasAnyFile(projectPath, ['sentry.*.config.*', '.sentryclirc', 'bugsnag.*']),
        hasAnyFile(projectPath, ['tsconfig.json', 'mypy.ini', 'pyrightconfig.json', '.flowconfig']),
        hasAnyFile(projectPath, ['.snyk', '.trivyignore', 'security.md', 'SECURITY.md']),
        hasAnyFile(projectPath, ['docs/**/*.md', 'doc/**/*', 'documentation/**/*']),
        fileExists(projectPath, 'CONTRIBUTING.md'),
        hasAnyFile(projectPath, ['CHANGELOG.md', '.changeset/*', '.releaserc*']),
        hasAnyFile(projectPath, ['backup*', 'docker-compose.yml']),
        hasAnyFile(projectPath, ['*.a11y.*', 'axe*', 'pa11y*']),
        hasAnyFile(projectPath, ['robots.txt', 'sitemap.xml', 'next-sitemap.config.*']),
        hasAnyFile(projectPath, ['lighthouse*', 'bundle-analyzer*', 'webpack-bundle*']),
        hasAnyFile(projectPath, ['seed.*', 'seeds/*', 'fixtures/*', 'prisma/seed.*']),
    ]);
    const [hasReadme, hasGitignore, hasEnvExample, hasLicense, hasEditorConfig, hasLinting, hasFormatting, hasTesting, hasCiCd, hasErrorTracking, hasTypeChecking, hasSecurityScanning, hasDocumentation, hasContributing, hasChangelogStrategy, hasBackupStrategy, hasAccessibility, hasSeo, hasPerformanceBudget, hasSeedData,] = checks;
    const trueCount = checks.filter(Boolean).length;
    const completenessScore = Math.round((trueCount / checks.length) * 100);
    return {
        hasReadme,
        hasGitignore,
        hasEnvExample,
        hasLicense,
        hasEditorConfig,
        hasLinting,
        hasFormatting,
        hasTesting,
        hasCiCd,
        hasErrorTracking,
        hasTypeChecking,
        hasSecurityScanning,
        hasDocumentation,
        hasContributing,
        hasChangelogStrategy,
        hasBackupStrategy,
        hasAccessibility,
        hasSeo,
        hasPerformanceBudget,
        hasSeedData,
        completenessScore,
    };
}
//# sourceMappingURL=analyzer.js.map