import { writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { getCodeIndex } from "./index-tools.js";
import { CODESIFT_INSTRUCTIONS } from "../instructions.js";
/**
 * Count symbols per top-level directory from the index.
 */
function countByDirectory(index) {
    const dirStats = new Map();
    for (const file of index.files) {
        const dir = getTopDirectory(file.path);
        const existing = dirStats.get(dir);
        if (existing) {
            existing.fileCount += 1;
            existing.symbolCount += file.symbol_count;
        }
        else {
            dirStats.set(dir, { fileCount: 1, symbolCount: file.symbol_count });
        }
    }
    return dirStats;
}
/**
 * Get the top-level directory from a file path.
 * For "src/tools/index.ts" returns "src/tools".
 * For "index.ts" returns ".".
 */
function getTopDirectory(filePath) {
    const lastSlash = filePath.lastIndexOf("/");
    if (lastSlash < 0)
        return ".";
    return filePath.slice(0, lastSlash);
}
/**
 * Count files per language.
 */
function countByLanguage(files) {
    const langCounts = new Map();
    for (const file of files) {
        langCounts.set(file.language, (langCounts.get(file.language) ?? 0) + 1);
    }
    return langCounts;
}
/**
 * Detect the tech stack from file patterns in the index.
 */
function detectTechStack(index) {
    const stack = [];
    const fileSet = new Set(index.files.map((f) => f.path));
    const extensions = new Set(index.files.map((f) => {
        const dot = f.path.lastIndexOf(".");
        return dot >= 0 ? f.path.slice(dot) : "";
    }));
    // TypeScript
    if (extensions.has(".ts") || extensions.has(".tsx")) {
        stack.push("TypeScript");
    }
    // JavaScript
    if (extensions.has(".js") || extensions.has(".jsx")) {
        stack.push("JavaScript");
    }
    // Python
    if (extensions.has(".py")) {
        stack.push("Python");
    }
    // Detect frameworks from common config files or paths
    const hasFile = (pattern) => {
        for (const path of fileSet) {
            if (path.includes(pattern))
                return true;
        }
        return false;
    };
    if (hasFile("next.config"))
        stack.push("Next.js");
    if (hasFile("vite.config"))
        stack.push("Vite");
    if (hasFile("nest-cli.json") || hasFile("@nestjs"))
        stack.push("NestJS");
    if (hasFile("prisma/schema.prisma"))
        stack.push("Prisma");
    if (hasFile("tailwind.config"))
        stack.push("Tailwind CSS");
    return stack;
}
/**
 * Format the language breakdown string.
 * Example: "typescript (45), javascript (12), python (3)"
 */
function formatLanguageBreakdown(langCounts) {
    const sorted = [...langCounts.entries()].sort((a, b) => b[1] - a[1]);
    return sorted.map(([lang, count]) => `${lang} (${count})`).join(", ");
}
/**
 * Generate a CLAUDE.md architecture overview for a repository.
 * Analyzes the index to produce a summary of files, symbols, languages,
 * and directory structure.
 */
export async function generateClaudeMd(repo, outputPath) {
    const index = await getCodeIndex(repo);
    if (!index) {
        throw new Error(`Repository not found: ${repo}`);
    }
    const langCounts = countByLanguage(index.files);
    const dirStats = countByDirectory(index);
    const techStack = detectTechStack(index);
    const lines = [];
    lines.push("## Architecture Overview (auto-generated by codesift)");
    lines.push("");
    // Summary line
    const langBreakdown = formatLanguageBreakdown(langCounts);
    lines.push(`**${index.file_count} files, ${index.symbol_count} symbols** | Languages: ${langBreakdown}`);
    // Tech stack if detected
    if (techStack.length > 0) {
        lines.push(`**Tech stack:** ${techStack.join(", ")}`);
    }
    lines.push("");
    // Directory breakdown, sorted by symbol count descending
    const sortedDirs = [...dirStats.entries()].sort((a, b) => b[1].symbolCount - a[1].symbolCount);
    for (const [dir, stats] of sortedDirs) {
        lines.push(`**${dir}/** (${stats.fileCount} files, ${stats.symbolCount} symbols)`);
    }
    lines.push("");
    lines.push("## CodeSift Usage Hints");
    lines.push("");
    lines.push(CODESIFT_INSTRUCTIONS);
    const content = lines.join("\n");
    if (outputPath) {
        // SEC-001: Validate output_path is within the repo root to prevent arbitrary file write
        const resolvedOutput = resolve(outputPath);
        const resolvedRoot = resolve(index.root);
        if (!resolvedOutput.startsWith(resolvedRoot + "/") && resolvedOutput !== resolvedRoot) {
            throw new Error(`output_path must be within the repository root: ${resolvedRoot}`);
        }
        try {
            await writeFile(resolvedOutput, content, "utf-8");
        }
        catch (err) {
            const message = err instanceof Error ? err.message : String(err);
            throw new Error(`Failed to write CLAUDE.md: ${message}`);
        }
        return { content, path: resolvedOutput };
    }
    return { content };
}
//# sourceMappingURL=generate-tools.js.map