"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanForWorkflows = scanForWorkflows;
exports.analyzeFile = analyzeFile;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const SKIP_DIRS = new Set(['node_modules', 'build', 'dist', '.git', '.docker-data', 'dashboard']);
const SKIP_PATTERNS = [/\.test\.ts$/, /\.spec\.ts$/, /\.compiled\.yaml$/, /\.d\.ts$/];
// ── Detection patterns ──────────────────────────────────────────────────
const HOTMESH_DURABLE = /(?:Durable\.workflow\.)?proxyActivities/;
const TEMPORAL_IMPORT = /@temporalio\/workflow/;
const WORKFLOW_PRIMITIVES = /(?:Durable\.workflow\.)?(sleep|condition|startChild|signal)/;
const COMPOSITION = /(?:executeChild|startChild|executeLT)/;
const EXPORTED_ASYNC = /export\s+async\s+function\s+(\w+)/g;
function detectFramework(source) {
    if (HOTMESH_DURABLE.test(source))
        return 'hotmesh-durable';
    if (TEMPORAL_IMPORT.test(source))
        return 'temporal';
    return null;
}
function hasWorkflowControlFlow(source) {
    return WORKFLOW_PRIMITIVES.test(source) || COMPOSITION.test(source);
}
function extractExportedFunctions(source) {
    const names = [];
    let match;
    const pattern = new RegExp(EXPORTED_ASYNC.source, 'g');
    while ((match = pattern.exec(source)) !== null) {
        names.push(match[1]);
    }
    return names;
}
function extractActivityNames(source) {
    const names = [];
    const pattern = /(?:const|let)\s*\{\s*([^}]+)\}\s*=\s*(?:Durable\.workflow\.)?proxyActivities/g;
    let match;
    while ((match = pattern.exec(source)) !== null) {
        for (const name of match[1].split(',')) {
            const trimmed = name.trim();
            if (trimmed)
                names.push(trimmed);
        }
    }
    return names;
}
function extractPrimitives(source) {
    const primitives = [];
    const seen = new Set();
    const pattern = /Durable\.workflow\.(\w+)/g;
    let match;
    while ((match = pattern.exec(source)) !== null) {
        const p = match[1];
        if (p !== 'proxyActivities' && !seen.has(p)) {
            seen.add(p);
            primitives.push(p);
        }
    }
    if (/conditionLT/.test(source) && !seen.has('conditionLT'))
        primitives.push('conditionLT');
    if (/executeLT/.test(source) && !seen.has('executeLT'))
        primitives.push('executeLT');
    return primitives;
}
function extractActivityImports(source) {
    const imports = [];
    const pattern = /import\s+\*\s+as\s+\w+\s+from\s+['"]([^'"]+)['"]/g;
    let match;
    while ((match = pattern.exec(source)) !== null) {
        imports.push(match[1]);
    }
    return imports;
}
// ── Public API ──────────────────────────────────────────────────────────
/**
 * Scan a directory tree for durable/temporal workflow files.
 * Returns discovered workflows sorted by path.
 */
function scanForWorkflows(rootDir, functionFilter) {
    const results = [];
    walkDir(rootDir, rootDir, results, functionFilter);
    return results.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
}
/**
 * Analyze a single file. Returns a DiscoveredWorkflow if it's a workflow, null otherwise.
 */
function analyzeFile(filePath, baseDir, functionFilter) {
    const source = fs.readFileSync(filePath, 'utf-8');
    const framework = detectFramework(source);
    if (!framework && !hasWorkflowControlFlow(source))
        return null;
    const exported = extractExportedFunctions(source);
    if (exported.length === 0)
        return null;
    const functionName = functionFilter
        ? exported.find((n) => n === functionFilter) || exported[0]
        : exported[0];
    return {
        path: filePath,
        relativePath: path.relative(baseDir, filePath),
        functionName,
        activities: extractActivityNames(source),
        primitives: extractPrimitives(source),
        activityImportPaths: extractActivityImports(source),
        framework: framework || 'unknown',
    };
}
function walkDir(dir, baseDir, results, functionFilter) {
    let entries;
    try {
        entries = fs.readdirSync(dir, { withFileTypes: true });
    }
    catch {
        return;
    }
    for (const entry of entries) {
        if (entry.isDirectory()) {
            if (SKIP_DIRS.has(entry.name))
                continue;
            walkDir(path.join(dir, entry.name), baseDir, results, functionFilter);
        }
        else if (entry.isFile() && entry.name.endsWith('.ts')) {
            if (SKIP_PATTERNS.some((p) => p.test(entry.name)))
                continue;
            const filePath = path.join(dir, entry.name);
            const workflow = analyzeFile(filePath, baseDir, functionFilter);
            if (workflow)
                results.push(workflow);
        }
    }
}
