"""E2E test for Knowledge Base — creates fake sources, ingests, compiles, researches, lints."""

import asyncio
import sys
from pathlib import Path

# Add server src to path
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))


SOURCES = {
    "alignment-survey-2026.md": """---
title: "A Survey of AI Alignment Approaches (2026)"
author: "Dr. Sarah Chen, MIT CSAIL"
date: "2026-03-15"
---

# A Survey of AI Alignment Approaches

## Abstract
This survey covers the major approaches to AI alignment as of early 2026, including RLHF, Constitutional AI, debate, and recursive reward modeling.

## Key Findings
- RLHF is used by >90% of production LLM systems
- Constitutional AI reduces reliance on human labelers by 70%
- Debate-based approaches remain largely theoretical
- Mechanistic interpretability identified >1000 meaningful features in GPT-4 class models

## People
- Dr. Sarah Chen (MIT) — survey lead
- Jan Leike (Anthropic) — scalable oversight
- Paul Christiano (ARC) — recursive reward modeling
- Chris Olah (Anthropic) — interpretability lead
- Ilya Sutskever — founded SSI in 2024

## Organizations
- Anthropic — Constitutional AI and interpretability
- ARC — alignment research
- MIRI — mathematical alignment
- DeepMind — reward modeling
""",
    "interpretability-breakthrough.md": """---
title: "Mechanistic Interpretability Breakthrough"
author: "Chris Olah, Anthropic Research Blog"
date: "2026-02-20"
---

# Mechanistic Interpretability Breakthrough

Using sparse autoencoders, we identified 10,000 interpretable features in Claude 3.5 Sonnet.

## What We Found
- Features represent clear concepts: code, ethics, math reasoning
- We can steer model behavior by adjusting features
- Safety-relevant features: deception, sycophancy, refusal
- Feature interactions reveal multi-step reasoning

## Implications for Safety
- Detect deception via feature activation
- Remove unwanted behaviors by suppressing features
- Verify alignment mechanistically

## Team
- Chris Olah (lead), Tom Brown, Dario Amodei, Amanda Askell

## Contradicts Yann LeCun's claim that interpretability is not useful for safety.
""",
    "eu-ai-act-implementation.md": """---
title: "EU AI Act: First Year Implementation Report"
author: "Reuters"
date: "2026-04-01"
---

# EU AI Act Implementation: Year One

## Compliance
- 78% of major providers submitted documentation
- Anthropic and Google achieved full compliance Q1 2026
- OpenAI received warning for incomplete transparency
- Meta open-source models create regulatory gray area

## Impact
- 12% compliance cost increase for EU startups
- 23% trust increase among EU consumers
- Brussels Effect spreading norms globally

## People
- Margrethe Vestager — architect of the Act
- Sam Altman — supported Act after initial opposition
- Yann LeCun — criticizes Act as innovation-killing
""",
    "ai-incidents-q1-2026.md": """---
title: "AI Incident Database Q1 2026"
author: "AIID"
date: "2026-04-02"
---

# AI Incidents Q1 2026

- 847 total incidents, 23 critical
- 312 involving foundation models, 156 involving agents
- Agent systems: 18% of incidents but 45% of critical ones
- Healthcare AI incidents down 30% vs Q4 2025
- Financial AI incidents up 15%

## Notable
- Citadel autonomous trading agent: $2.3M loss
- Cleveland Clinic diagnosis AI: 34 misclassified cases
- YouTube content moderation: 50,000 legitimate videos removed
- Delta Airlines chatbot: $180K unauthorized refunds
""",
    "dario-amodei-interview.md": """---
title: "Dario Amodei Interview on AI Safety"
author: "Lex Fridman Podcast #432"
date: "2026-03-28"
---

# Dario Amodei on AI Safety

On Anthropic: "We started Anthropic because we believed the most important thing was making AI safe."

On Constitutional AI: "Our answer to RLHF scalability. Give the model a constitution and have it self-improve."

On Interpretability: "Chris Olah's work is the most important safety research anywhere."

On EU AI Act: "Regulation done right can accelerate safety research."

On Ilya Sutskever and SSI: "Ilya is brilliant. SSI focusing purely on safe superintelligence is bold."
""",
}


def write_sources():
    """Write test source files to the KB raw/ directory."""
    from agntspace.infra.config import get_settings
    settings = get_settings()
    raw_dir = settings.vault_dir / "kb" / "ai-safety-research" / "raw"
    raw_dir.mkdir(parents=True, exist_ok=True)

    for name, content in SOURCES.items():
        (raw_dir / name).write_text(content, encoding="utf-8")
        print(f"  Written: {name}")
    print(f"\n{len(SOURCES)} source files written to {raw_dir}\n")


async def run_e2e():
    import httpx

    base = "http://127.0.0.1:8000"
    async with httpx.AsyncClient(base_url=base, timeout=120) as client:

        # Step 1: Check KB exists
        print("=" * 60)
        print("STEP 1: Verify KB")
        print("=" * 60)
        resp = await client.get("/api/kb/ai-safety-research")
        status = resp.json()
        print(f"  Raw pending: {status.get('raw_count', status.get('raw_pending', '?'))}")
        print()

        # Step 2: Ingest
        print("=" * 60)
        print("STEP 2: Ingest sources")
        print("=" * 60)
        resp = await client.post("/api/kb/ai-safety-research/ingest")
        result = resp.json()
        print(f"  Ingested: {result.get('count', 0)} sources")
        print(f"  Files: {result.get('ingested', [])}")
        print(f"  Wiki updates: {result.get('wiki_updates', [])}")
        print()

        # Step 3: Compile wiki
        print("=" * 60)
        print("STEP 3: Compile wiki")
        print("=" * 60)
        resp = await client.post("/api/kb/ai-safety-research/compile?full=true")
        result = resp.json()
        print(f"  Articles compiled: {result.get('count', 0)}")
        print(f"  Articles: {result.get('articles', [])}")
        print()

        # Step 4: Check status
        print("=" * 60)
        print("STEP 4: KB Status")
        print("=" * 60)
        resp = await client.get("/api/kb/ai-safety-research")
        status = resp.json()
        for key in ("raw_count", "library_count", "entity_count", "concept_count", "source_count"):
            if key in status:
                print(f"  {key}: {status[key]}")
        print()

        # Step 5: Research
        print("=" * 60)
        print("STEP 5: Research query")
        print("=" * 60)
        resp = await client.post("/api/kb/ai-safety-research/research",
            json={"query": "What are the main approaches to AI alignment and which is most promising?", "save_output": True})
        result = resp.json()
        print(f"  Answer ({len(result.get('answer', ''))} chars):")
        answer = result.get("answer", "")
        print(f"  {answer[:500]}...")
        print(f"  Output saved: {result.get('output_path', 'none')}")
        print()

        # Step 6: Research -> file to wiki
        print("=" * 60)
        print("STEP 6: Research -> file to wiki")
        print("=" * 60)
        resp = await client.post("/api/kb/ai-safety-research/research",
            json={"query": "Compare Constitutional AI vs RLHF", "file_to_wiki": True})
        result = resp.json()
        print(f"  Filed to wiki: {result.get('filed_to_wiki', False)}")
        print(f"  Path: {result.get('output_path', 'none')}")
        print()

        # Step 7: Lint
        print("=" * 60)
        print("STEP 7: Lint / health check")
        print("=" * 60)
        resp = await client.post("/api/kb/ai-safety-research/lint")
        result = resp.json()
        print(f"  Issues: {result.get('issue_count', 0)}")
        for issue in result.get("issues", [])[:5]:
            print(f"    {issue}")
        print(f"  Suggestions: {result.get('suggestion_count', 0)}")
        for sug in result.get("suggestions", [])[:5]:
            print(f"    {sug}")
        print()

        # Step 8: Wiki API
        print("=" * 60)
        print("STEP 8: Wiki API")
        print("=" * 60)
        resp = await client.get("/api/wiki/stats")
        stats = resp.json()
        print(f"  KBs: {stats.get('knowledge_bases', 0)}")
        print(f"  Articles: {stats.get('total_articles', 0)}")
        print(f"  Sources: {stats.get('total_sources', 0)}")

        resp = await client.get("/api/wiki/categories")
        cats = resp.json()
        print(f"  Categories: {[c['name'] for c in cats]}")

        resp = await client.get("/api/wiki/articles?limit=10")
        articles = resp.json()
        print(f"  Article list ({len(articles)}):")
        for a in articles[:10]:
            print(f"    - {a['title']} [{a.get('category', '')}] ({len(a.get('links', []))} links)")

        resp = await client.get("/api/wiki/people")
        people = resp.json()
        print(f"  People detected: {len(people)}")
        for p in people[:5]:
            print(f"    - {p['name']} ({p['mentions']} mentions)")
        print()

        # Step 9: Check log
        print("=" * 60)
        print("STEP 9: Operation log")
        print("=" * 60)
        resp = await client.get("/api/kb/ai-safety-research/log")
        log_data = resp.json()
        print(f"  Log entries: {log_data.get('entries', 0)}")
        # Show last few lines
        content = log_data.get("content", "")
        lines = [l for l in content.split("\n") if l.startswith("## [")]
        for l in lines[-5:]:
            print(f"    {l}")
        print()

        # Step 10: Verify files on disk
        print("=" * 60)
        print("STEP 10: Files on disk")
        print("=" * 60)

    from agntspace.infra.config import get_settings
    settings = get_settings()
    kb_dir = settings.vault_dir / "kb" / "ai-safety-research"

    for subdir in ["raw", "library", "wiki/entities", "wiki/concepts", "wiki/sources", "output"]:
        d = kb_dir / subdir
        if d.exists():
            files = list(d.glob("**/*"))
            files = [f for f in files if f.is_file() and f.name != ".gitkeep"]
            print(f"  {subdir}/: {len(files)} files")
            for f in files[:5]:
                print(f"    - {f.name}")
        else:
            print(f"  {subdir}/: (not created)")

    print()
    print("=" * 60)
    print("E2E TEST COMPLETE")
    print("=" * 60)


if __name__ == "__main__":
    print("Writing test sources...\n")
    write_sources()
    print("Running E2E test...\n")
    asyncio.run(run_e2e())
