// Planu — Analyzer: Linting, Conventions, Environments, Tooling, External Services
// Internal helpers extracted from analyzer.ts to keep file sizes manageable.
import { fileExists, hasAnyFile, collectDependencies } from '../detection-utils.js';
import { analyzeLintingEnhanced } from '../analyzer-linting.js';
// === Linting Analysis — delegates to enhanced module (SPEC-025) ===
export async function analyzeLinting(projectPath) {
    return analyzeLintingEnhanced(projectPath);
}
// === Convention Detection ===
// eslint-disable-next-line max-lines-per-function, complexity -- checklist pattern for AI agent configs
export async function detectConventions(projectPath) {
    const conventions = {};
    // AI agent configs — detect all major AI coding platforms
    if (await fileExists(projectPath, 'CLAUDE.md')) {
        conventions['ai-rules'] = 'CLAUDE.md';
    }
    if (await fileExists(projectPath, '.cursorrules')) {
        conventions['cursor-rules'] = '.cursorrules';
    }
    if (await fileExists(projectPath, '.windsurfrules')) {
        conventions['windsurf-rules'] = '.windsurfrules';
    }
    if (await fileExists(projectPath, '.clinerules')) {
        conventions['cline-rules'] = '.clinerules';
    }
    if (await fileExists(projectPath, '.github/copilot-instructions.md')) {
        conventions['copilot-rules'] = '.github/copilot-instructions.md';
    }
    if (await fileExists(projectPath, 'AGENTS.md')) {
        conventions['codex-rules'] = 'AGENTS.md';
    }
    if (await fileExists(projectPath, 'devin.md')) {
        conventions['devin-rules'] = 'devin.md';
    }
    if (await hasAnyFile(projectPath, ['.continue/config.json', '.continuerc.json'])) {
        conventions['continue-rules'] = '.continue/config.json';
    }
    if (await hasAnyFile(projectPath, ['.aider.conf.yml'])) {
        conventions['aider-rules'] = '.aider.conf.yml';
    }
    if (await hasAnyFile(projectPath, ['.gemini/settings.json', '.idx/dev.nix'])) {
        conventions['gemini-rules'] = '.gemini/settings.json';
    }
    if (await hasAnyFile(projectPath, ['.amazonq/rules.md', '.amazonq/settings.json'])) {
        conventions['amazon-q-rules'] = '.amazonq/rules.md';
    }
    if (await fileExists(projectPath, '.junie/guidelines.md')) {
        conventions['junie-rules'] = '.junie/guidelines.md';
    }
    if (await fileExists(projectPath, '.sourcegraph/cody.json')) {
        conventions['cody-rules'] = '.sourcegraph/cody.json';
    }
    if (await fileExists(projectPath, '.replit')) {
        conventions['replit-rules'] = '.replit';
    }
    if (await hasAnyFile(projectPath, ['.zed/settings.json'])) {
        conventions['zed-rules'] = '.zed/settings.json';
    }
    if (await hasAnyFile(projectPath, ['.augment/config.json', '.augmentignore'])) {
        conventions['augment-rules'] = '.augment/config.json';
    }
    if (await fileExists(projectPath, '.qodo/config.json')) {
        conventions['qodo-rules'] = '.qodo/config.json';
    }
    if (await fileExists(projectPath, '.kilocode/rules')) {
        conventions['kilo-code-rules'] = '.kilocode/rules';
    }
    if (await fileExists(projectPath, '.tabnine/config.json')) {
        conventions['tabnine-rules'] = '.tabnine/config.json';
    }
    if (await hasAnyFile(projectPath, ['.agent/rules/*', '.agent/workflows/*'])) {
        conventions['antigravity-rules'] = '.agent/rules/';
    }
    if (await fileExists(projectPath, 'GEMINI.md')) {
        // GEMINI.md is used by both Antigravity and Gemini CLI
        conventions['antigravity-rules'] ??= 'GEMINI.md';
        conventions['gemini-rules'] = 'GEMINI.md';
    }
    // Editor config
    if (await fileExists(projectPath, '.editorconfig')) {
        conventions['editor-config'] = '.editorconfig';
    }
    // Commit conventions
    if (await hasAnyFile(projectPath, ['commitlint.config.*', '.commitlintrc*'])) {
        conventions['commit-convention'] = 'conventional-commits';
    }
    // Git hooks
    if (await fileExists(projectPath, '.husky')) {
        conventions['git-hooks'] = 'husky';
    }
    if (await hasAnyFile(projectPath, ['.lefthook.yml', 'lefthook.yml'])) {
        conventions['git-hooks'] = 'lefthook';
    }
    if (await hasAnyFile(projectPath, ['.pre-commit-config.yaml'])) {
        conventions['git-hooks'] = 'pre-commit';
    }
    // Lint-staged
    if (await hasAnyFile(projectPath, ['.lintstagedrc*', 'lint-staged.config.*'])) {
        conventions['lint-staged'] = 'lint-staged';
    }
    return conventions;
}
// === Environment Detection ===
export async function detectEnvironments(projectPath) {
    const environments = ['development'];
    if (await hasAnyFile(projectPath, ['.env.staging', '.env.test', '.env.production'])) {
        if (await fileExists(projectPath, '.env.staging')) {
            environments.push('staging');
        }
        if (await fileExists(projectPath, '.env.test')) {
            environments.push('test');
        }
        if (await fileExists(projectPath, '.env.production')) {
            environments.push('production');
        }
    }
    else {
        environments.push('staging', 'production');
    }
    return environments;
}
// === External Services Detection ===
export async function detectExternalServices(projectPath) {
    const services = new Set();
    const deps = await collectDependencies(projectPath);
    const serviceMap = {
        stripe: ['stripe', '@stripe/stripe-js'],
        aws: ['aws-sdk', '@aws-sdk/client-s3', '@aws-sdk/client-ses'],
        'google-cloud': ['@google-cloud/storage', '@google-cloud/pubsub', '@google-cloud/firestore'],
        azure: ['@azure/storage-blob', '@azure/cosmos'],
        supabase: ['@supabase/supabase-js', '@supabase/ssr'],
        firebase: ['firebase', 'firebase-admin'],
        twilio: ['twilio'],
        sendgrid: ['@sendgrid/mail'],
        resend: ['resend'],
        cloudflare: ['@cloudflare/workers-types', 'wrangler'],
        vercel: ['@vercel/analytics', '@vercel/og'],
        sentry: ['@sentry/node', '@sentry/nextjs', '@sentry/react'],
        datadog: ['dd-trace'],
        'new-relic': ['newrelic'],
        redis: ['redis', 'ioredis'],
        elasticsearch: ['@elastic/elasticsearch'],
        algolia: ['algoliasearch'],
        openai: ['openai'],
        anthropic: ['@anthropic-ai/sdk'],
        auth0: ['@auth0/nextjs-auth0', 'auth0'],
        clerk: ['@clerk/nextjs', '@clerk/clerk-sdk-node'],
    };
    for (const [service, packages] of Object.entries(serviceMap)) {
        for (const pkg of packages) {
            if (deps.has(pkg)) {
                services.add(service);
                break;
            }
        }
    }
    return [...services];
}
// === Tooling Detection ===
// eslint-disable-next-line complexity -- checklist pattern for tooling detection
export async function detectTooling(projectPath) {
    const tooling = {};
    // CI/CD
    if (await hasAnyFile(projectPath, ['.github/workflows/*'])) {
        tooling.ci = 'github-actions';
    }
    else if (await fileExists(projectPath, '.gitlab-ci.yml')) {
        tooling.ci = 'gitlab-ci';
    }
    else if (await fileExists(projectPath, 'Jenkinsfile')) {
        tooling.ci = 'jenkins';
    }
    else if (await hasAnyFile(projectPath, ['.circleci/config.yml'])) {
        tooling.ci = 'circleci';
    }
    // Containers
    if (await fileExists(projectPath, 'Dockerfile')) {
        tooling.container = 'docker';
    }
    if (await hasAnyFile(projectPath, ['docker-compose.yml', 'docker-compose.yaml'])) {
        tooling.orchestration = 'docker-compose';
    }
    if (await hasAnyFile(projectPath, ['k8s/**/*', 'kubernetes/**/*'])) {
        tooling.orchestration = 'kubernetes';
    }
    // Build tools / task runners
    if (await fileExists(projectPath, 'turbo.json')) {
        tooling.monorepo = 'turborepo';
    }
    else if (await fileExists(projectPath, 'nx.json')) {
        tooling.monorepo = 'nx';
    }
    else if (await fileExists(projectPath, 'lerna.json')) {
        tooling.monorepo = 'lerna';
    }
    // Bundlers
    const deps = await collectDependencies(projectPath);
    if (deps.has('vite')) {
        tooling.bundler = 'vite';
    }
    else if (deps.has('webpack')) {
        tooling.bundler = 'webpack';
    }
    else if (deps.has('esbuild')) {
        tooling.bundler = 'esbuild';
    }
    else if (deps.has('rollup')) {
        tooling.bundler = 'rollup';
    }
    else if (deps.has('tsup')) {
        tooling.bundler = 'tsup';
    }
    else if (deps.has('turbopack')) {
        tooling.bundler = 'turbopack';
    }
    // Testing
    if (deps.has('vitest')) {
        tooling.testing = 'vitest';
    }
    else if (deps.has('jest')) {
        tooling.testing = 'jest';
    }
    else if (deps.has('mocha')) {
        tooling.testing = 'mocha';
    }
    else if (await fileExists(projectPath, 'pytest.ini')) {
        tooling.testing = 'pytest';
    }
    else if (await fileExists(projectPath, 'Cargo.toml')) {
        tooling.testing = 'cargo-test';
    }
    return tooling;
}
//# sourceMappingURL=detectors.js.map