"""Tests for export handlers and factory."""

import json

import pytest

from caliper._annotation import Annotation
from caliper._config import DevConfig
from caliper._export import DevHandler, create_handler
from caliper._record import Record


def _make_record(**overrides) -> Record:
    defaults = {
        "request_id": "test-uuid",
        "timestamp": "2026-02-20T10:00:00+00:00",
        "provider": "anthropic",
        "model": "claude-sonnet-4-20250514",
        "endpoint": "chat",
        "duration_ms": 150,
        "tokens_input": 100,
        "tokens_output": 50,
        "tokens_total": 150,
        "status": "success",
        "cached": False,
        "sdk_version": "0.1.0",
    }
    defaults.update(overrides)
    return Record(**defaults)


# ---------------------------------------------------------------------------
# Factory tests
# ---------------------------------------------------------------------------


def test_create_handler_dev():
    config = DevConfig(file_path="test.jsonl")
    handler = create_handler("dev", config)
    assert isinstance(handler, DevHandler)


def test_create_handler_unknown_target():
    config = DevConfig()
    with pytest.raises(ValueError, match="Unknown export target"):
        create_handler("kafka", config)


# ---------------------------------------------------------------------------
# DevHandler tests
# ---------------------------------------------------------------------------


def test_dev_handler_writes_jsonl(tmp_path):
    path = tmp_path / "records.jsonl"
    handler = DevHandler(path=str(path))

    records = [_make_record(model="model-a"), _make_record(model="model-b")]
    handler.export(records)

    lines = path.read_text().strip().split("\n")
    assert len(lines) == 2
    assert json.loads(lines[0])["model"] == "model-a"
    assert json.loads(lines[1])["model"] == "model-b"


def test_dev_handler_appends(tmp_path):
    path = tmp_path / "records.jsonl"
    handler = DevHandler(path=str(path))

    handler.export([_make_record(model="first")])
    handler.export([_make_record(model="second")])

    records = handler.get_records()
    assert len(records) == 2
    assert records[0]["model"] == "first"
    assert records[1]["model"] == "second"


def test_dev_handler_get_records_empty(tmp_path):
    path = tmp_path / "nonexistent.jsonl"
    handler = DevHandler(path=str(path))
    assert handler.get_records() == []


def test_dev_handler_clear(tmp_path):
    path = tmp_path / "records.jsonl"
    handler = DevHandler(path=str(path))
    handler.export([_make_record()])
    assert len(handler.get_records()) == 1

    handler.clear()
    assert handler.get_records() == []


# ---------------------------------------------------------------------------
# DevHandler annotation tests
# ---------------------------------------------------------------------------


def test_dev_handler_writes_annotations_jsonl(tmp_path):
    records_path = tmp_path / "records.jsonl"
    annotations_path = tmp_path / "annotations.jsonl"
    handler = DevHandler(path=str(records_path), annotations_path=str(annotations_path))

    annotations = [
        Annotation(request_id="req-1", timestamp="2026-02-20T10:00:00+00:00", metadata={"sentiment": "positive"}),
        Annotation(request_id="req-2", timestamp="2026-02-20T10:01:00+00:00", metadata={"label": "good"}),
    ]
    handler.export_annotations(annotations)

    lines = annotations_path.read_text().strip().split("\n")
    assert len(lines) == 2
    assert json.loads(lines[0])["request_id"] == "req-1"
    assert json.loads(lines[1])["metadata"] == {"label": "good"}


def test_dev_handler_get_annotations(tmp_path):
    records_path = tmp_path / "records.jsonl"
    annotations_path = tmp_path / "annotations.jsonl"
    handler = DevHandler(path=str(records_path), annotations_path=str(annotations_path))

    handler.export_annotations(
        [
            Annotation(request_id="req-1", timestamp="2026-02-20T10:00:00+00:00", metadata={"k": "v"}),
        ]
    )

    result = handler.get_annotations()
    assert len(result) == 1
    assert result[0]["request_id"] == "req-1"


def test_dev_handler_clear_removes_both_files(tmp_path):
    records_path = tmp_path / "records.jsonl"
    annotations_path = tmp_path / "annotations.jsonl"
    handler = DevHandler(path=str(records_path), annotations_path=str(annotations_path))

    handler.export([_make_record()])
    handler.export_annotations(
        [
            Annotation(request_id="req-1", timestamp="2026-02-20T10:00:00+00:00", metadata={"k": "v"}),
        ]
    )
    assert len(handler.get_records()) == 1
    assert len(handler.get_annotations()) == 1

    handler.clear()
    assert handler.get_records() == []
    assert handler.get_annotations() == []
