// engine/architecture-pattern-detector/actor-temporal-detector.ts — Actor Model, Temporal (SPEC-033)
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { glob } from 'glob';
// === Actor Model ===
/** Detects Actor Model framework from dependencies and code patterns */
export async function detectActorModel(projectPath) {
    const indicators = [];
    let actorFramework;
    // Check for Erlang/Elixir OTP files
    try {
        const elixirFiles = await glob('**/*.{ex,erl}', {
            cwd: projectPath,
            nodir: true,
            ignore: ['node_modules/**'],
        });
        if (elixirFiles.length > 0) {
            // Sample up to 5 files for code patterns
            for (const f of elixirFiles.slice(0, 5)) {
                try {
                    const content = await readFile(join(projectPath, f), 'utf-8');
                    if (/use GenServer|use Supervisor|gen_statem/i.test(content)) {
                        indicators.push(`otp-genserver in ${f}`);
                        actorFramework = 'otp';
                        break;
                    }
                }
                catch {
                    // ignore
                }
            }
        }
    }
    catch {
        // ignore
    }
    // Check for Akka in build files
    try {
        const buildFiles = ['build.sbt', 'pom.xml', 'build.gradle', 'build.gradle.kts'];
        for (const bf of buildFiles) {
            try {
                const content = await readFile(join(projectPath, bf), 'utf-8');
                if (/akka[-.]actor|akka[-.]stream/i.test(content)) {
                    indicators.push(`akka-dependency in ${bf}`);
                    actorFramework = 'akka';
                }
            }
            catch {
                // ignore
            }
        }
    }
    catch {
        // ignore
    }
    // Check package.json for actor libraries
    try {
        const pkg = await readFile(join(projectPath, 'package.json'), 'utf-8');
        if (/"proto-actor"/i.test(pkg)) {
            indicators.push('proto-actor-dependency');
            actorFramework = 'proto-actor';
        }
    }
    catch {
        // ignore
    }
    // Check for Orleans (.grain files in C#)
    try {
        const grainFiles = await glob('**/*.grain.cs', {
            cwd: projectPath,
            nodir: true,
            ignore: ['node_modules/**'],
        });
        if (grainFiles.length > 0) {
            indicators.push(`orleans-grain-files: ${grainFiles.length}`);
            actorFramework = 'orleans';
        }
    }
    catch {
        // ignore
    }
    if (indicators.length === 0) {
        return null;
    }
    return {
        name: 'actor-model',
        confidence: indicators.length >= 2 ? 'detected' : 'inferred',
        indicators,
        actorFramework,
    };
}
// === Temporal / Durable Execution ===
/** Detects Temporal, Inngest, Restate or Conductor from dependencies */
export async function detectTemporal(projectPath) {
    const indicators = [];
    let provider;
    const temporalDeps = {
        '@temporalio/client': 'temporal',
        '@temporalio/worker': 'temporal',
        '@temporalio/activity': 'temporal',
        'go.temporal.io/sdk': 'temporal',
        temporalio: 'temporal',
        'io.temporal': 'temporal',
        inngest: 'inngest',
        '@inngest/inngest': 'inngest',
        '@restatedev/restate-sdk': 'restate',
        'conductor-client': 'conductor',
    };
    try {
        const pkg = await readFile(join(projectPath, 'package.json'), 'utf-8');
        for (const [dep, prov] of Object.entries(temporalDeps)) {
            if (pkg.includes(dep)) {
                indicators.push(`temporal-dependency: ${dep}`);
                provider = prov;
                break;
            }
        }
    }
    catch {
        // ignore
    }
    // Check for workflow files
    try {
        const workflowFiles = await glob('**/*.{workflow.ts,activity.ts}', {
            cwd: projectPath,
            nodir: true,
            ignore: ['node_modules/**'],
        });
        if (workflowFiles.length > 0) {
            indicators.push(`workflow-files: ${workflowFiles.length}`);
        }
    }
    catch {
        // ignore
    }
    try {
        const inngestFile = await glob('**/inngest.{ts,js}', {
            cwd: projectPath,
            nodir: true,
            ignore: ['node_modules/**'],
        });
        if (inngestFile.length > 0) {
            indicators.push('inngest-config-file');
            /* v8 ignore start */
            provider ??= 'inngest';
            /* v8 ignore stop */
        }
    }
    catch {
        // ignore
    }
    if (indicators.length === 0) {
        return null;
    }
    return {
        name: 'temporal',
        confidence: indicators.length >= 2 ? 'detected' : 'inferred',
        indicators,
        durableExecutionProvider: provider,
    };
}
//# sourceMappingURL=actor-temporal-detector.js.map