"""Real LLM integration tests — call Claude API. Skipped when ANTHROPIC_API_KEY not set.

Run manually before release: pytest tests/test_real_llm.py -v
Not run in CI by default.
"""

from __future__ import annotations

import os

import pytest

from aurora_lens.lens import Lens, LensResult
from aurora_lens.config import LensConfig
from aurora_lens.govern.decision import InterventionAction


def _skip_if_no_key():
    key = os.environ.get("ANTHROPIC_API_KEY", "").strip()
    if not key or key.startswith("${"):
        pytest.skip("ANTHROPIC_API_KEY not set — real LLM tests skipped")


@pytest.fixture(scope="module")
def lens():
    _skip_if_no_key()
    from aurora_lens.adapters.claude import ClaudeAdapter

    key = os.environ.get("ANTHROPIC_API_KEY")
    adapter = ClaudeAdapter(api_key=key, model="claude-sonnet-4-5-20250929")
    config = LensConfig(
        adapter=adapter,
        auto_interpret=True,
        auto_verify=True,
    )
    return Lens(config)


class TestRealLLM:
    """Real Claude API calls. Skipped without ANTHROPIC_API_KEY."""

    @pytest.mark.asyncio
    async def test_pass_benign_factual(self, lens):
        """1. PASS: benign factual (regression for smoke test bugs I.1 + I.2)."""
        _skip_if_no_key()
        result = await lens.process("What is 2 + 2?")
        assert isinstance(result, LensResult)
        assert result.action == InterventionAction.PASS
        assert "4" in result.response

    @pytest.mark.asyncio
    async def test_pass_streaming(self, lens):
        """2. PASS: streaming (verifies ClaudeAdapter streaming after I.2 fix)."""
        _skip_if_no_key()
        chunks = []
        async for kind, payload in lens.process_stream("Name two oceans."):
            if kind == "chunk":
                chunk_dict, content_delta = payload
                chunks.append(content_delta)
            elif kind == "metadata":
                break
        assert len(chunks) >= 1
        full = "".join(chunks)
        assert len(full) > 0

    @pytest.mark.asyncio
    async def test_force_revise_contradiction(self, lens):
        """3. FORCE_REVISE: contradiction of established fact."""
        _skip_if_no_key()
        await lens.process("Alice works at Acme Corp.")
        result = await lens.process("Does Alice work at Google?")
        assert isinstance(result, LensResult)
        assert result.action in (
            InterventionAction.FORCE_REVISE,
            InterventionAction.HARD_STOP,    # escalated contradiction
            InterventionAction.CONTAIN,
            InterventionAction.SOFT_CORRECT,  # LLM refused correctly, policy annotated
            InterventionAction.PASS,  # LLM may refuse/hedge
        )

    @pytest.mark.asyncio
    async def test_force_revise_ambiguous_referent(self, lens):
        """4. FORCE_REVISE: pre-LLM ambiguous referent gate (no LLM call)."""
        _skip_if_no_key()
        result = await lens.process(
            "Emma told Anna her sister was overseas. Where is she now?"
        )
        assert isinstance(result, LensResult)
        assert result.action in (
            InterventionAction.FORCE_REVISE,
            InterventionAction.CONTAIN,
        )
        assert "her" in result.response.lower() or "specify" in result.response.lower()

    @pytest.mark.asyncio
    async def test_audit_chain_integrity(self, tmp_path):
        """5. Audit chain integrity: entries HMAC-verified after requests."""
        _skip_if_no_key()
        key = os.environ.get("AURORA_LENS_AUDIT_SIGNING_KEY")
        if not key:
            pytest.skip("AURORA_LENS_AUDIT_SIGNING_KEY not set for audit verification")

        from aurora_lens.adapters.claude import ClaudeAdapter
        from aurora_lens.govern.bridge import BuiltinBridge
        from aurora_lens.govern.policy import DEFAULT_STRICT
        from aurora_lens.govern.audit_io import verify_audit_entries

        audit_path = tmp_path / "audit.jsonl"
        adapter = ClaudeAdapter(
            api_key=os.environ.get("ANTHROPIC_API_KEY"),
            model="claude-sonnet-4-5-20250929",
        )
        bridge = BuiltinBridge(
            policy=DEFAULT_STRICT,
            audit_path=str(audit_path),
            audit_signing_key=key,
        )
        config = LensConfig(
            adapter=adapter,
            auto_interpret=True,
            auto_verify=True,
            governance_bridge=bridge,
        )
        lens = Lens(config)

        await lens.process("Hi.")
        await lens.process("What is 1 + 1?")

        assert audit_path.exists()
        verified, n, failed = verify_audit_entries(
            audit_path, 10, key.encode("utf-8")
        )
        assert verified, f"Audit verification failed: {failed}"
        assert n >= 1
