// engine/architecture-pattern-detector/monolith-composable-detector.ts — Modular Monolith, Composable/MACH (SPEC-033)
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { glob } from 'glob';
// === Modular Monolith ===
/** Detects Modular Monolith from modules directory and boundary enforcement */
export async function detectModularMonolith(projectPath) {
    const indicators = [];
    // Check for modules/ directory structure
    try {
        const modules = await glob('+(src/modules|modules)/*/index.{ts,js}', {
            cwd: projectPath,
            nodir: true,
        });
        if (modules.length >= 2) {
            indicators.push(`modules-directory with ${modules.length} module(s)`);
        }
    }
    catch {
        // ignore
    }
    // Check for nx.json with enforce-module-boundaries
    try {
        const nxJson = await readFile(join(projectPath, 'nx.json'), 'utf-8');
        if (/enforce.*module.*boundaries|@nx\/enforce-module-boundaries/i.test(nxJson)) {
            indicators.push('nx-enforce-module-boundaries');
        }
    }
    catch {
        // ignore
    }
    // Check ESLint config for no-restricted-imports between modules
    const eslintFiles = [
        '.eslintrc.json',
        '.eslintrc.js',
        '.eslintrc.cjs',
        'eslint.config.js',
        'eslint.config.cjs',
    ];
    for (const eslintFile of eslintFiles) {
        try {
            const content = await readFile(join(projectPath, eslintFile), 'utf-8');
            if (/no-restricted-imports.*modules|modules.*no-restricted-imports/i.test(content)) {
                indicators.push(`eslint-module-boundaries in ${eslintFile}`);
                break;
            }
        }
        catch {
            // ignore
        }
    }
    if (indicators.length < 2) {
        return null;
    }
    return {
        name: 'modular-monolith',
        confidence: 'detected',
        indicators,
    };
}
// === Composable / MACH ===
/** Detects Composable/MACH architecture from headless CMS and commerce dependencies */
export async function detectComposable(projectPath) {
    const indicators = [];
    const machComponents = [];
    const cmsDeps = [
        'contentful',
        '@contentful/rich-text-react-renderer',
        '@sanity/client',
        'sanity',
        '@strapi/strapi',
    ];
    const commerceDeps = [
        '@shopify/storefront-api-client',
        '@shopify/hydrogen',
        '@commercetools/sdk-client-v2',
    ];
    try {
        const pkg = await readFile(join(projectPath, 'package.json'), 'utf-8');
        for (const dep of cmsDeps) {
            if (pkg.includes(dep)) {
                indicators.push(`headless-cms: ${dep}`);
                machComponents.push('cms-headless');
                break;
            }
        }
        for (const dep of commerceDeps) {
            if (pkg.includes(dep)) {
                indicators.push(`headless-commerce: ${dep}`);
                machComponents.push('commerce-headless');
                break;
            }
        }
    }
    catch {
        // ignore
    }
    // Check README for MACH keywords
    try {
        const readme = await readFile(join(projectPath, 'README.md'), 'utf-8');
        if (/\bMACH\b|composable\s+architecture|API.first|headless\s+CMS/i.test(readme)) {
            indicators.push('readme-mach-keywords');
        }
    }
    catch {
        // ignore
    }
    if (indicators.length < 2) {
        return null;
    }
    return {
        name: 'composable',
        confidence: indicators.length >= 3 ? 'detected' : 'inferred',
        indicators,
        machComponents,
    };
}
//# sourceMappingURL=monolith-composable-detector.js.map