import { readFile, stat } from "node:fs/promises";
import { basename, join } from "node:path";
const MAX_ENTRYPOINT_BYTES = 96 * 1024;
const ENTRYPOINT_PATTERNS = [
    /^src\/main\.[a-z0-9]+$/i,
    /^src\/index\.[a-z0-9]+$/i,
    /^src\/lib\.[a-z0-9]+$/i,
    /^src\/main\.rs$/i,
    /^src\/lib\.rs$/i,
    /^main\.rs$/i,
    /^lib\.rs$/i,
    /^app\/[^/]+\.[a-z0-9]+$/i,
];
export async function discoverEntrypointSemantics(cwd, inventory) {
    const candidatePaths = Array.from(new Set([...inventory.rootEntries, ...inventory.sourceRoots.flatMap((root) => likelyEntrypoints(root))]));
    const entrypoints = [];
    const modules = [];
    const architectureHints = [];
    const unknowns = [];
    for (const path of candidatePaths
        .filter((path) => ENTRYPOINT_PATTERNS.some((pattern) => pattern.test(path)))
        .slice(0, 16)) {
        const text = await safeReadSmall(join(cwd, path));
        if (!text)
            continue;
        entrypoints.push({
            path,
            kind: detectKind(path),
            value: summarizeEntrypoint(path, text),
            confidence: "medium",
            sources: [path],
        });
        architectureHints.push(...extractImports(path, text));
    }
    for (const root of inventory.sourceRoots) {
        modules.push({ path: root, value: inferModuleResponsibility(root), confidence: "low", sources: [root] });
    }
    if (entrypoints.length === 0) {
        unknowns.push({
            value: "No small central entrypoint detected by ThreadSuite heuristics.",
            confidence: "medium",
            sources: inventory.sourceRoots,
        });
    }
    return { entrypoints, modules, architectureHints, unknowns };
}
function likelyEntrypoints(root) {
    return [
        `${root}/main.ts`,
        `${root}/main.js`,
        `${root}/index.ts`,
        `${root}/index.js`,
        `${root}/lib.ts`,
        `${root}/lib.rs`,
        `${root}/main.rs`,
        `${root}/src/main.ts`,
        `${root}/src/main.js`,
        `${root}/src/index.ts`,
        `${root}/src/index.js`,
        `${root}/src/lib.ts`,
        `${root}/src/lib.rs`,
        `${root}/src/main.rs`,
    ];
}
async function safeReadSmall(path) {
    try {
        const stats = await stat(path);
        if (stats.size > MAX_ENTRYPOINT_BYTES)
            return undefined;
        return await readFile(path, "utf-8");
    }
    catch {
        return undefined;
    }
}
function detectKind(path) {
    if (path.endsWith(".rs"))
        return "rust";
    if (/\.[cm]?[jt]sx?$/i.test(path))
        return "javascript/typescript";
    return "source";
}
function summarizeEntrypoint(path, text) {
    const firstComment = text.match(/^\s*(?:\/\/|#|\/\*)\s*(.+)$/m)?.[1]?.trim();
    const exports = Array.from(text.matchAll(/\bexport\s+(?:async\s+)?(?:function|class|const|interface|type)\s+([A-Za-z0-9_]+)/g))
        .map((match) => match[1])
        .slice(0, 8);
    const functions = Array.from(text.matchAll(/\b(?:fn|function)\s+([A-Za-z0-9_]+)/g))
        .map((match) => match[1])
        .slice(0, 8);
    return [
        `Entrypoint candidate ${path}.`,
        firstComment ? `Top comment: ${firstComment}` : undefined,
        exports.length > 0 ? `Exports: ${exports.join(", ")}` : undefined,
        functions.length > 0 ? `Functions: ${functions.join(", ")}` : undefined,
    ]
        .filter((line) => Boolean(line))
        .join(" ");
}
function extractImports(path, text) {
    const imports = Array.from(text.matchAll(/\b(?:import .* from ["']([^"']+)["']|use\s+([a-zA-Z0-9_:]+))/g))
        .map((match) => match[1] ?? match[2] ?? "")
        .filter(Boolean)
        .slice(0, 12);
    return imports.map((item) => ({
        value: `Entrypoint ${path} imports/uses ${item}.`,
        confidence: "low",
        sources: [path],
    }));
}
function inferModuleResponsibility(path) {
    const name = basename(path).toLowerCase();
    if (name.includes("test"))
        return `${path} appears to contain tests.`;
    if (name === "src")
        return `${path} appears to contain primary source code.`;
    if (name === "packages")
        return `${path} appears to contain workspace packages.`;
    if (name === "crates")
        return `${path} appears to contain Rust crates.`;
    return `${path} is a source/module root.`;
}
//# sourceMappingURL=entrypoint-scanner.js.map