"""Tests for DeepSigma LangChain tools."""
import json

import pytest

from langchain_deepsigma import (
    AuditTool,
    CoherenceScorerTool,
    IRISQueryTool,
    ReconcilerTool,
    deepsigma_tools,
)
from coherence_ops import MemoryGraph, DLRBuilder


SAMPLE_EPISODES = [
    {
        "episodeId": "ep-test-001",
        "decisionType": "Deploy",
        "startedAt": "2026-01-01T00:00:00Z",
        "endedAt": "2026-01-01T00:00:05Z",
        "actor": {"type": "agent", "id": "test-agent", "version": "1.0"},
        "context": {"evidenceRefs": []},
        "truth": {"claims": []},
        "actions": [],
        "degrade": {"step": "ideal"},
        "policy": {"packId": "test-pack", "packHash": "abc123", "result": "allow"},
        "verification": {"result": "pass", "verifierId": "smoke-test"},
        "outcome": {"code": "success", "detail": "deployed ok"},
        "seal": {"sealHash": "sha256:abc", "sealedAt": "2026-01-01T00:00:05Z", "version": 1},
    }
]

SAMPLE_EPISODES_JSON = json.dumps(SAMPLE_EPISODES)


class TestCoherenceScorerTool:
    def test_returns_grade(self):
        tool = CoherenceScorerTool()
        result = tool._run(episodes=SAMPLE_EPISODES_JSON)
        assert "Grade:" in result
        assert "/100" in result

    def test_returns_dimensions(self):
        tool = CoherenceScorerTool()
        result = tool._run(episodes=SAMPLE_EPISODES_JSON)
        assert "Dimensions:" in result
        assert "policy_adherence" in result or "outcome_health" in result

    def test_invalid_json_returns_error(self):
        tool = CoherenceScorerTool()
        result = tool._run(episodes="not-json")
        assert "Error" in result

    def test_with_drift_events(self):
        drift = json.dumps([{
            "driftId": "drift-001",
            "episodeId": "ep-test-001",
            "driftType": "outcome",
            "severity": "yellow",
            "detectedAt": "2026-01-01T00:00:10Z",
            "fingerprint": {"key": "outcome/test", "version": 1},
        }])
        tool = CoherenceScorerTool()
        result = tool._run(episodes=SAMPLE_EPISODES_JSON, drift_events=drift)
        assert "Grade:" in result


class TestAuditTool:
    def test_returns_pass_or_fail(self):
        tool = AuditTool()
        result = tool._run(episodes=SAMPLE_EPISODES_JSON)
        assert "PASSED" in result or "FAILED" in result

    def test_returns_audit_id(self):
        tool = AuditTool()
        result = tool._run(episodes=SAMPLE_EPISODES_JSON)
        assert "audit-lc-" in result

    def test_invalid_json(self):
        tool = AuditTool()
        result = tool._run(episodes="bad")
        assert "Error" in result


class TestReconcilerTool:
    def test_returns_reconciliation_header(self):
        tool = ReconcilerTool()
        result = tool._run(episodes=SAMPLE_EPISODES_JSON)
        assert "Reconciliation complete" in result

    def test_shows_auto_and_manual_counts(self):
        tool = ReconcilerTool()
        result = tool._run(episodes=SAMPLE_EPISODES_JSON)
        assert "Auto-fixable" in result
        assert "Manual" in result

    def test_invalid_json(self):
        tool = ReconcilerTool()
        result = tool._run(episodes="bad")
        assert "Error" in result


class TestIRISQueryTool:
    def test_status_query(self):
        mg = MemoryGraph()
        for ep in SAMPLE_EPISODES:
            mg.add_episode(ep)
        dlr = DLRBuilder()
        dlr.from_episodes(SAMPLE_EPISODES)
        tool = IRISQueryTool(mg=mg, dlr=dlr)
        result = tool._run(query_type="STATUS")
        assert "IRIS STATUS" in result
        assert "Status:" in result

    def test_why_query_with_episode(self):
        mg = MemoryGraph()
        for ep in SAMPLE_EPISODES:
            mg.add_episode(ep)
        tool = IRISQueryTool(mg=mg)
        result = tool._run(query_type="WHY", target="ep-test-001")
        assert "IRIS WHY" in result

    def test_default_mg_created_if_none(self):
        tool = IRISQueryTool()
        result = tool._run(query_type="STATUS")
        assert "IRIS STATUS" in result


class TestDeepSigmaToolsFactory:
    def test_returns_four_tools(self):
        tools = deepsigma_tools()
        assert len(tools) == 4

    def test_tool_names(self):
        tools = deepsigma_tools()
        names = {t.name for t in tools}
        assert names == {"iris_query", "coherence_score", "coherence_audit", "coherence_reconcile"}

    def test_wires_mg_to_iris(self):
        mg = MemoryGraph()
        tools = deepsigma_tools(mg=mg)
        iris = next(t for t in tools if t.name == "iris_query")
        assert iris._mg is mg
