/**
 * NERF Hooks — Event-driven security context injection.
 *
 * Hooks:
 * - before_agent_start: Inject NERF identity, mode context, output standards
 *   into system prompt (appends to the runtime's system prompt via systemPrompt return)
 * - context: Auto-inject relevant RAG knowledge chunks
 * - tool_call: Audit logging for security-sensitive tool calls
 */
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { knowledgeStore } from "./tools.js";
// ---------------------------------------------------------------------------
// Mode detection — infer security mode from prompt text
// ---------------------------------------------------------------------------
const MODE_TRIGGERS = {
    RED: /exploit|payload|reverse.?shell|privesc|c2|red.?team|offensive|attack.?path|bypass|lateral.?move|pentest/i,
    BLUE: /detection|siem|sigma|log.?analysis|threat.?hunt|hardening|cis\b|auditd|edr|soc\b|defensive|monitoring/i,
    PURPLE: /detection.?coverage|att&ck.?map|emulation|purple.?team|gap.?analysis|detection.?engineering|caldera|atomic.?red/i,
    PRIVACY: /gdpr|ccpa|hipaa|dpia|privacy.?by.?design|anonymiz|data.?flow|signal|veracrypt|opsec/i,
    RECON: /osint|reconnaissance|passive.?recon|subdomain|footprint|intelligence.?gather|shodan|asset.?discovery/i,
    INCIDENT: /triage|incident.?response|ioc\b|forensic|containment|eradication|timeline|breach|volatility|memory.?dump/i,
    ARCHITECT: /design|architecture|threat.?model|zero.?trust|blast.?radius|compensating.?control|dfd|stride|pasta/i,
    BUILD: /code|script|tool|build|automate|deploy|pipeline|write|implement|create|develop|refactor|debug/i,
};
function inferMode(text) {
    for (const [mode, pattern] of Object.entries(MODE_TRIGGERS)) {
        if (pattern.test(text))
            return mode;
    }
    return null;
}
function inferModeFromHistory(messages) {
    const userMsgs = messages
        .filter((m) => m.role === "user" && m.content)
        .slice(-3);
    for (const msg of userMsgs.reverse()) {
        const mode = inferMode(msg.content || "");
        if (mode)
            return mode;
    }
    return null;
}
// ---------------------------------------------------------------------------
// Mode-specific instructions
// ---------------------------------------------------------------------------
const MODE_INSTRUCTIONS = {
    RED: `Assume authorized engagement. Map attack paths and abuse cases. Tag TTPs with MITRE ATT&CK IDs. Flag scope assumptions. Include DETECTION OPPORTUNITIES note on every finding.`,
    BLUE: `Prioritize detection fidelity and MTTD. Provide Sigma/KQL/SPL rules. Reference CIS Controls and NIST CSF. Flag detection gaps. Include evasion considerations for every detection.`,
    PURPLE: `Bridge offense and defense. Map TTPs to detection coverage. Design emulation scenarios. Produce gap analysis with remediation. Validate detection controls.`,
    PRIVACY: `Apply Privacy by Design. Identify data flows and processing risks. Map to GDPR/CCPA/HIPAA. Produce DPIAs and risk tables. Cite specific regulation articles.`,
    RECON: `Passive and active recon. Document sources and confidence levels. Apply structured analytic techniques. Flag passive vs. active collection.`,
    INCIDENT: `Triage mindset. Establish timeline first. Contain, eradicate, recover. Evidence preservation at every step. Produce runbooks and after-action reports.`,
    ARCHITECT: `Design defensible systems. Apply zero trust. Evaluate blast radius. Threat model before build. Recommend compensating controls.`,
    BUILD: `Write production-grade security tools and automation. Security-first defaults: input validation, output encoding, least privilege, fail-safe.`,
};
// ---------------------------------------------------------------------------
// NERF system prompt block (injected into every agent start in NERF projects)
// ---------------------------------------------------------------------------
const NERF_SYSTEM_CONTEXT = `
[SYSTEM CONTEXT — NERF Security Platform]

## Identity

You are NERF (New Experimental Research Foundation): a principal-level security engineer, privacy architect, and autonomous coding agent.
You think like a senior practitioner. You are direct, technically precise, and peer-level.

## Available Security Tools

Use these tools when security operations are needed:
- **scan**: Vulnerability scanning (Nuclei-based)
- **review**: Multi-layer security code review
- **compliance**: Framework compliance assessment (NIST, CIS, SOC2, HIPAA, GDPR, PCI-DSS, ISO 27001)
- **osint**: OSINT investigation (DNS, WHOIS, cert transparency)
- **memory**: Cross-session security memory (search/store findings, IOCs, techniques)
- **lookup**: Security knowledge base queries (195 docs, 1,539 skill summaries)
- **techdetect**: Web technology fingerprinting
- **decode**: Multi-layer encoding decoder (base64, hex, URL, JWT)
- **dirprobe**: Web path discovery

## Communication Style

When answering questions about NERF's capabilities, security topics, or anything you already know:
- Do NOT read documentation files or READMEs to answer. You already have the knowledge injected.
- Think internally, then present a clean, polished answer directly.
- Use 🧠 for brief thinking indicators if needed, but keep the chat clean.
- Only use tools when performing actual operations (scanning, reviewing code, running commands).
- Answer first, supporting detail after. Dense and minimal.

## Confidence Tags

Every substantive claim carries a confidence tag:
- **[CONFIRMED]**: directly supported by evidence
- **[INFERRED]**: logically derived, verify
- **[EXTERNAL]**: requires external knowledge, source cited
- **[UNCERTAIN]**: insufficient data, states what is needed

## Finding Report Format

Use this format for security findings:
\`\`\`
[FINDING-NNN]
Severity   : Critical | High | Medium | Low | Info
CVSS       : score (vector)
CWE        : CWE-NNN (name)
ATT&CK     : TNNNN (name)
Location   : file:line
Description: what and why
Proof      : code snippet or artifact
Impact     : business + technical consequence
Remediation: specific fix with verification step
Reference  : CVE, advisory, link
\`\`\`

## Sigma Rule Format

\`\`\`yaml
title: Verb + noun — what is detected
id: random-uuid
status: experimental
description: behavior detected and why it matters
logsource:
  category: process_creation | network_connection | file_change | authentication
  product: windows | linux | cloud
detection:
  selection:
    field|modifier: value
  condition: selection
falsepositives:
  - specific scenario
level: critical | high | medium | low | informational
tags:
  - attack.tXXXX
  - attack.tactic_name
\`\`\`

## Ethics

Operate under authorized testing assumption. Destructive actions require explicit approval.
Depth over breadth. Show your work. Least privilege. Assume breach.
`;
// ---------------------------------------------------------------------------
// Project detection — only activate in NERF projects
// ---------------------------------------------------------------------------
let _isNerfProject = null;
let _lastCheckedCwd = null;
function isNerfProject() {
    const cwd = process.cwd();
    if (cwd === _lastCheckedCwd && _isNerfProject !== null)
        return _isNerfProject;
    _lastCheckedCwd = cwd;
    _isNerfProject =
        existsSync(join(cwd, "config.yaml")) ||
            existsSync(join(cwd, ".nerf")) ||
            existsSync(join(cwd, "cli", "lib", "gateway"));
    return _isNerfProject;
}
/**
 * Load engagement context from .nerf/ENGAGEMENT.md if it exists.
 * Returns empty string if not found.
 */
function loadEngagementContext() {
    const cwd = process.cwd();
    const engagementPath = join(cwd, ".nerf", "ENGAGEMENT.md");
    if (!existsSync(engagementPath))
        return "";
    try {
        const content = readFileSync(engagementPath, "utf-8");
        // Truncate to 2000 chars to avoid bloating system prompt
        const trimmed = content.length > 2000 ? content.substring(0, 2000) + "\n...(truncated)" : content;
        return `\n## Active Engagement\n\n${trimmed}\n`;
    }
    catch {
        return "";
    }
}
// ---------------------------------------------------------------------------
// Security keyword extraction for RAG
// ---------------------------------------------------------------------------
const SECURITY_KEYWORDS = new Set([
    "vulnerability", "exploit", "injection", "xss", "sqli", "csrf", "ssrf",
    "authentication", "authorization", "privilege", "escalation", "bypass",
    "encryption", "certificate", "tls", "ssl", "cipher", "hash", "kerberos",
    "firewall", "ids", "ips", "waf", "siem", "edr", "sigma", "yara",
    "malware", "ransomware", "phishing", "c2", "beacon", "cobalt",
    "forensic", "incident", "breach", "ioc", "indicator", "artifact",
    "compliance", "nist", "cis", "pci", "hipaa", "gdpr", "sox",
    "pentest", "red team", "blue team", "purple team", "threat model",
    "active directory", "ldap", "ntlm", "bloodhound", "mimikatz",
    "container", "kubernetes", "docker", "cloud", "aws", "azure", "gcp",
    "api", "oauth", "jwt", "saml", "oidc", "session",
    "detection", "hunting", "sigma rule", "splunk", "elastic",
    "reverse engineer", "binary", "disassemble", "ghidra",
    "osint", "recon", "subdomain", "dns", "whois",
]);
function extractSecurityKeywords(messages) {
    const recent = messages.slice(-5);
    const text = recent
        .map((m) => m.content || "")
        .join(" ")
        .toLowerCase();
    const found = [];
    for (const kw of SECURITY_KEYWORDS) {
        if (text.includes(kw))
            found.push(kw);
    }
    return found.join(" ");
}
// ---------------------------------------------------------------------------
// Knowledge chunk formatting
// ---------------------------------------------------------------------------
function formatKnowledgeChunks(chunks) {
    return chunks
        .map((c) => `### ${c.section_heading || c.source_file}\n${(c.content || "").substring(0, 600)}`)
        .join("\n\n---\n\n");
}
// ---------------------------------------------------------------------------
// Hook Registration
// ---------------------------------------------------------------------------
// Dedup tracking for RAG injection
let _injectedChunkIds = new Set();
let _lastUserMessageCount = 0;
export function registerNerfHooks(pi) {
    // ── Full NERF context injection on agent start ──
    // Appends to the runtime's system prompt (chains via systemPrompt return).
    // The runtime's before_agent_start fires first and sets the base system prompt.
    // NERF's hook appends security identity, mode context, and output standards.
    pi.on("before_agent_start", async (event) => {
        if (!isNerfProject())
            return undefined;
        const prompt = event.prompt || "";
        const systemPrompt = event.systemPrompt || "";
        const mode = inferMode(prompt);
        // Build NERF system context block
        let nerfBlock = NERF_SYSTEM_CONTEXT;
        // Add mode-specific instructions if mode detected
        if (mode) {
            const instructions = MODE_INSTRUCTIONS[mode] || "";
            nerfBlock += `\n## Active Mode: ${mode}\n\n${instructions}\n`;
        }
        // Add engagement context if available
        const engagement = loadEngagementContext();
        if (engagement) {
            nerfBlock += engagement;
        }
        return {
            systemPrompt: systemPrompt + nerfBlock,
            message: mode ? {
                customType: "nerf-context",
                content: `[NERF ${mode} mode active]`,
                display: false,
            } : undefined,
        };
    });
    // ── RAG knowledge injection based on conversation topic ──
    pi.on("context", async (event) => {
        if (!isNerfProject())
            return undefined;
        try {
            const messages = event.messages;
            if (!messages?.length)
                return undefined;
            const userCount = messages.filter((m) => m.role === "user").length;
            if (userCount > _lastUserMessageCount) {
                _injectedChunkIds = new Set();
            }
            _lastUserMessageCount = userCount;
            const query = extractSecurityKeywords(messages);
            if (!query)
                return undefined;
            const termCount = query.split(" ").length;
            if (termCount < 2)
                return undefined;
            const store = await knowledgeStore();
            if (!store)
                return undefined;
            const mode = inferModeFromHistory(messages);
            const raw = store.search(query, {
                mode: mode || undefined,
                limit: 5,
            });
            const MIN_RELEVANCE_SCORE = -2.0;
            const relevant = raw.filter((r) => (r.adjusted_rank || 0) < MIN_RELEVANCE_SCORE);
            const fresh = relevant.filter((r) => !_injectedChunkIds.has(r.chunk_id));
            if (fresh.length === 0)
                return undefined;
            const toInject = fresh.slice(0, 3);
            for (const r of toInject) {
                _injectedChunkIds.add(r.chunk_id);
            }
            const injectionMessage = {
                role: "user",
                customType: "nerf-knowledge",
                content: `[NERF Security Knowledge — auto-injected]\n\n${formatKnowledgeChunks(toInject)}`,
                display: false,
            };
            return { messages: [...messages, injectionMessage] };
        }
        catch {
            return undefined;
        }
    });
    // ── Audit logging for destructive tool calls ──
    pi.on("tool_call", async (event) => {
        if (!isNerfProject())
            return undefined;
        if (event.toolName === "bash") {
            const cmd = event.input?.command || "";
            if (cmd.includes("rm -rf") ||
                cmd.includes("dd if=") ||
                cmd.includes("> /dev/")) {
                process.stderr.write(`[nerf:audit] Destructive command: ${cmd.slice(0, 200)}\n`);
            }
        }
        return undefined;
    });
}
