// engine/auditor-architecture.ts — SOLID and Architecture checks
// Extracted from auditor.ts to stay within 400-line limit.
import { relative } from 'node:path';
// === SOLID Checks ===
export function checkSolid(file, content, _lines, ext) {
    const findings = [];
    // SRP: Files with too many exports/classes
    const exportCount = (content.match(/\bexport\b/g) ?? []).length;
    const classCount = (content.match(/\bclass\s+\w+/g) ?? []).length;
    if (classCount > 2) {
        findings.push({
            file,
            category: 'solid',
            severity: 'warning',
            rule: 'srp-multiple-classes',
            message: `File contains ${classCount} classes, suggesting multiple responsibilities.`,
            suggestion: 'Move each class to its own file. A file should have one primary reason to change.',
            reference: 'Single Responsibility Principle',
        });
    }
    if (exportCount > 15) {
        findings.push({
            file,
            category: 'solid',
            severity: 'info',
            rule: 'srp-too-many-exports',
            message: `File has ${exportCount} exports, suggesting it may have too many responsibilities.`,
            suggestion: 'Consider splitting into focused modules with fewer public exports.',
            reference: 'Single Responsibility Principle',
        });
    }
    // OCP: Long switch/if-else chains
    const switchCount = (content.match(/\bswitch\s*\(/g) ?? []).length;
    if (switchCount > 0) {
        const caseCount = (content.match(/\bcase\s+/g) ?? []).length;
        if (caseCount > 7) {
            findings.push({
                file,
                category: 'solid',
                severity: 'warning',
                rule: 'ocp-long-switch',
                message: `Switch statement with ${caseCount} cases. Adding new behavior requires modifying this file.`,
                suggestion: 'Consider using a strategy pattern, registry, or polymorphism for extensibility.',
                reference: 'Open/Closed Principle',
            });
        }
    }
    // ISP: Large interfaces (TypeScript specific)
    if (ext === '.ts' || ext === '.tsx') {
        const interfaces = content.matchAll(/interface\s+(\w+)\s*\{([^}]*)\}/gs);
        for (const match of interfaces) {
            if (match[2]) {
                const memberCount = match[2].split(';').filter((s) => s.trim()).length;
                if (memberCount > 8) {
                    findings.push({
                        file,
                        category: 'solid',
                        severity: 'info',
                        rule: 'isp-large-interface',
                        message: `Interface "${match[1]}" has ${memberCount} members. Clients may depend on methods they don't use.`,
                        suggestion: 'Split into smaller, role-specific interfaces.',
                        reference: 'Interface Segregation Principle',
                    });
                }
            }
        }
    }
    // DIP: Direct instantiation of dependencies
    const directNew = content.matchAll(/new\s+(Http|Database|Redis|Mongo|Prisma|Sequelize|Mongoose)\w*/g);
    for (const match of directNew) {
        findings.push({
            file,
            category: 'solid',
            severity: 'warning',
            rule: 'dip-direct-instantiation',
            message: `Direct instantiation of ${match[1]}* in business logic.`,
            suggestion: 'Inject dependencies through constructor or function parameters instead.',
            reference: 'Dependency Inversion Principle',
        });
    }
    return findings;
}
// === Architecture Checks ===
export function checkArchitecture(file, content, lines, projectPath) {
    const findings = [];
    const relFile = relative(projectPath, file);
    // UI logic in data layer
    if (/(?:repositories|models|db|data)\//i.exec(relFile) &&
        /(?:useState|useEffect|createElement|render|component|\.jsx|\.tsx)/i.exec(content)) {
        findings.push({
            file,
            category: 'architecture',
            severity: 'error',
            rule: 'layer-violation-ui-in-data',
            message: 'UI/presentation logic detected in data/infrastructure layer.',
            suggestion: 'Move UI logic to presentation layer. Data layer should only handle persistence.',
            reference: 'Separation of Concerns',
        });
    }
    // Data access in presentation layer
    if (/(?:components|pages|views|screens)\//i.exec(relFile) &&
        /(?:query|INSERT|UPDATE|DELETE|SELECT|db\.|prisma\.|mongoose\.)/i.exec(content)) {
        if (!content.includes('react-query') && !content.includes('tanstack')) {
            findings.push({
                file,
                category: 'architecture',
                severity: 'warning',
                rule: 'layer-violation-data-in-ui',
                message: 'Direct data access detected in presentation layer.',
                suggestion: 'Use a service/repository layer to abstract data access from UI components.',
                reference: 'Separation of Concerns',
            });
        }
    }
    // God files (too many imports)
    const importLines = lines.filter((l) => /^(?:import|from|require|use)\b/.exec(l) ??
        /^\s*import\s+/.exec(l) ??
        /^\s*const\s+\w+\s*=\s*require/.exec(l));
    if (importLines.length > 20) {
        findings.push({
            file,
            category: 'architecture',
            severity: 'warning',
            rule: 'too-many-dependencies',
            message: `File has ${importLines.length} imports, suggesting too many dependencies.`,
            suggestion: 'This file may be a "God module". Consider splitting by domain or responsibility.',
            reference: 'High Cohesion, Low Coupling',
        });
    }
    return findings;
}
//# sourceMappingURL=auditor-architecture.js.map