# tests/test_api.py
"""Tests for the CrashSense REST API (Flask test client, no network calls)."""

import json

import pytest

from crashsense.api import create_app
from crashsense.core.memory import MemoryStore


@pytest.fixture
def client(tmp_path):
    """Create a Flask test client backed by a temp database."""
    db_path = str(tmp_path / "test_api.db")
    app = create_app(db_path=db_path)
    app.config["TESTING"] = True
    with app.test_client() as c:
        # Pre-populate some data
        store = MemoryStore(db_path)
        for i in range(3):
            rec = store.save_diagnosis(
                tx_hash=f"0x{'a' * 63}{i}",
                chain="ethereum" if i < 2 else "polygon",
                summary=f"Summary {i}",
                root_cause=f"Root cause {i}",
                suggested_fix=f"Fix {i}",
                status="failed",
                provider="gemini",
                patterns=["INSUFFICIENT_BALANCE"] if i == 0 else [],
                remediation=[{"pattern": "INSUFFICIENT_BALANCE"}] if i == 0 else [],
            )
            store.log_action(rec.id, "llm_call", f"Called LLM for tx {i}", {"provider": "gemini"})
        yield c


@pytest.fixture
def empty_client(tmp_path):
    """Flask test client with an empty database."""
    db_path = str(tmp_path / "test_api_empty.db")
    app = create_app(db_path=db_path)
    app.config["TESTING"] = True
    with app.test_client() as c:
        yield c


# ── Health endpoint ───────────────────────────────────────────────────────

class TestHealth:
    def test_health(self, client):
        resp = client.get("/api/v1/health")
        assert resp.status_code == 200
        data = resp.get_json()
        assert data["status"] == "ok"
        assert data["service"] == "crashsense"


# ── History list ──────────────────────────────────────────────────────────

class TestListHistory:
    def test_list_all(self, client):
        resp = client.get("/api/v1/history")
        assert resp.status_code == 200
        data = resp.get_json()
        assert data["total"] == 3
        assert len(data["items"]) == 3
        assert data["page"] == 1

    def test_pagination(self, client):
        resp = client.get("/api/v1/history?page=1&per_page=2")
        data = resp.get_json()
        assert len(data["items"]) == 2
        assert data["pages"] == 2

        resp2 = client.get("/api/v1/history?page=2&per_page=2")
        data2 = resp2.get_json()
        assert len(data2["items"]) == 1

    def test_empty_db(self, empty_client):
        resp = empty_client.get("/api/v1/history")
        data = resp.get_json()
        assert data["total"] == 0
        assert data["items"] == []


# ── Get by hash ───────────────────────────────────────────────────────────

class TestGetByHash:
    def test_found(self, client):
        tx = "0x" + "a" * 63 + "0"
        resp = client.get(f"/api/v1/history/{tx}")
        assert resp.status_code == 200
        data = resp.get_json()
        assert data["tx_hash"] == tx
        assert data["summary"] == "Summary 0"

    def test_not_found(self, client):
        resp = client.get("/api/v1/history/0x" + "f" * 64)
        assert resp.status_code == 404
        assert resp.get_json()["error"] == "not_found"


# ── Search ────────────────────────────────────────────────────────────────

class TestSearch:
    def test_search_hit(self, client):
        resp = client.get("/api/v1/history/search?q=Summary 0")
        assert resp.status_code == 200
        data = resp.get_json()
        assert data["count"] >= 1

    def test_search_no_query(self, client):
        resp = client.get("/api/v1/history/search")
        assert resp.status_code == 400
        assert "missing_query" in resp.get_json()["error"]

    def test_search_no_results(self, client):
        resp = client.get("/api/v1/history/search?q=zzzznotfound")
        data = resp.get_json()
        assert data["count"] == 0


# ── Actions ───────────────────────────────────────────────────────────────

class TestActions:
    def test_get_actions(self, client):
        resp = client.get("/api/v1/history/1/actions")
        assert resp.status_code == 200
        data = resp.get_json()
        assert data["diagnosis_id"] == 1
        assert data["count"] >= 1
        assert data["actions"][0]["action_type"] == "llm_call"

    def test_no_actions(self, client):
        resp = client.get("/api/v1/history/9999/actions")
        data = resp.get_json()
        assert data["count"] == 0


# ── Stats ─────────────────────────────────────────────────────────────────

class TestStats:
    def test_stats(self, client):
        resp = client.get("/api/v1/stats")
        assert resp.status_code == 200
        data = resp.get_json()
        assert data["total_diagnoses"] == 3
        assert "by_chain" in data
        assert "by_provider" in data
