/**
 * NERF Workflow Templates — Registry & Resolution
 *
 * Loads the workflow template registry and resolves templates by name,
 * alias, or trigger-keyword matching against user input.
 */
import { readFileSync, existsSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { homedir } from "node:os";
const __extensionDir = resolveNerfExtensionDir();
const registryPath = join(__extensionDir, "workflow-templates", "registry.json");
/** Resolve the NERF extension dir with fallback to ~/.nerf/agent/extensions/nerf-engine/. */
function resolveNerfExtensionDir() {
    const moduleDir = dirname(fileURLToPath(import.meta.url));
    if (existsSync(join(moduleDir, "workflow-templates")))
        return moduleDir;
    const nerfHome = process.env.NERF_HOME || join(homedir(), ".nerf");
    const agentNerfDir = join(nerfHome, "agent", "extensions", "nerf");
    if (existsSync(join(agentNerfDir, "workflow-templates")))
        return agentNerfDir;
    return moduleDir;
}
// ─── Registry Cache ──────────────────────────────────────────────────────────
let cachedRegistry = null;
/**
 * Load and cache the workflow template registry.
 */
export function loadRegistry() {
    if (cachedRegistry)
        return cachedRegistry;
    const content = readFileSync(registryPath, "utf-8");
    cachedRegistry = JSON.parse(content);
    return cachedRegistry;
}
/**
 * Resolve a template by exact name or alias.
 * Returns null if no match found.
 */
export function resolveByName(nameOrAlias) {
    const registry = loadRegistry();
    const normalized = nameOrAlias.toLowerCase().trim();
    // Exact key match
    if (registry.templates[normalized]) {
        return {
            id: normalized,
            template: registry.templates[normalized],
            confidence: "exact",
        };
    }
    // Match by template name (case-insensitive)
    for (const [id, entry] of Object.entries(registry.templates)) {
        if (entry.name.toLowerCase() === normalized) {
            return { id, template: entry, confidence: "exact" };
        }
    }
    // Fuzzy: prefix match on id
    for (const [id, entry] of Object.entries(registry.templates)) {
        if (id.startsWith(normalized) || normalized.startsWith(id)) {
            return { id, template: entry, confidence: "high" };
        }
    }
    // Common aliases
    const aliases = {
        "bug": "bugfix",
        "fix": "bugfix",
        "feature": "small-feature",
        "feat": "small-feature",
        "research": "spike",
        "investigate": "spike",
        "hot": "hotfix",
        "urgent": "hotfix",
        "security": "security-audit",
        "audit": "security-audit",
        "upgrade": "dep-upgrade",
        "deps": "dep-upgrade",
        "update-deps": "dep-upgrade",
        "migration": "refactor",
        "project": "full-project",
        "full": "full-project",
    };
    const aliasMatch = aliases[normalized];
    if (aliasMatch && registry.templates[aliasMatch]) {
        return {
            id: aliasMatch,
            template: registry.templates[aliasMatch],
            confidence: "high",
        };
    }
    return null;
}
/**
 * Auto-detect the best template based on user description text.
 * Returns ranked matches sorted by confidence.
 */
export function autoDetect(description) {
    const registry = loadRegistry();
    const lower = description.toLowerCase();
    const words = lower.split(/\s+/);
    const matches = [];
    for (const [id, entry] of Object.entries(registry.templates)) {
        let bestScore = 0;
        let bestTrigger = "";
        for (const trigger of entry.triggers) {
            const triggerLower = trigger.toLowerCase();
            // Exact phrase match in description
            if (lower.includes(triggerLower)) {
                const score = triggerLower.split(/\s+/).length * 2; // multi-word triggers score higher
                if (score > bestScore) {
                    bestScore = score;
                    bestTrigger = trigger;
                }
                continue;
            }
            // Single-word trigger match against description words
            if (!triggerLower.includes(" ") && words.includes(triggerLower)) {
                if (1 > bestScore) {
                    bestScore = 1;
                    bestTrigger = trigger;
                }
            }
        }
        if (bestScore > 0) {
            const confidence = bestScore >= 4 ? "high" : bestScore >= 2 ? "medium" : "low";
            matches.push({
                id,
                template: entry,
                confidence,
                matchedTrigger: bestTrigger,
            });
        }
    }
    // Sort by confidence (high > medium > low), then alphabetically
    const order = { exact: 0, high: 1, medium: 2, low: 3 };
    matches.sort((a, b) => order[a.confidence] - order[b.confidence] || a.id.localeCompare(b.id));
    return matches;
}
/**
 * List all templates as formatted text for display.
 */
export function listTemplates() {
    const registry = loadRegistry();
    const lines = ["Workflow Templates\n"];
    for (const [id, entry] of Object.entries(registry.templates)) {
        const phases = entry.phases.join(" → ");
        const complexity = entry.estimated_complexity;
        lines.push(`  ${id.padEnd(16)} ${entry.name}`);
        lines.push(`  ${"".padEnd(16)} ${entry.description}`);
        lines.push(`  ${"".padEnd(16)} Phases: ${phases}  |  Complexity: ${complexity}`);
        lines.push("");
    }
    lines.push("Usage: /nerf start <template> [description]");
    lines.push("       /nerf templates info <name>");
    return lines.join("\n");
}
/**
 * Get detailed info about a specific template.
 */
export function getTemplateInfo(name) {
    const match = resolveByName(name);
    if (!match)
        return null;
    const { id, template: t } = match;
    const lines = [
        `Template: ${t.name} (${id})`,
        "",
        `Description: ${t.description}`,
        `Complexity:  ${t.estimated_complexity}`,
        `Requires .nerf/: ${t.requires_project ? "yes" : "no"}`,
        "",
        "Phases:",
        ...t.phases.map((p, i) => `  ${i + 1}. ${p}`),
        "",
        "Triggers:",
        `  ${t.triggers.join(", ")}`,
    ];
    if (t.artifact_dir) {
        lines.push("", `Artifacts: ${t.artifact_dir}`);
    }
    const templateFilePath = join(__extensionDir, "workflow-templates", t.file);
    if (existsSync(templateFilePath)) {
        lines.push("", "Template file: loaded");
    }
    else {
        lines.push("", "Template file: not yet created");
    }
    return lines.join("\n");
}
/**
 * Load the raw content of a workflow template .md file.
 */
export function loadWorkflowTemplate(templateId) {
    const match = resolveByName(templateId);
    if (!match)
        return null;
    const filePath = join(__extensionDir, "workflow-templates", match.template.file);
    if (!existsSync(filePath))
        return null;
    return readFileSync(filePath, "utf-8");
}
