"""Tests for CostTracker token usage and cost estimation."""

from __future__ import annotations

from koan.telemetry.cost import CostTracker, UsageRecord


class TestCostTracker:
    def test_record_returns_usage_record(self) -> None:
        tracker = CostTracker()
        rec = tracker.record("gpt-4o", input_tokens=1000, output_tokens=500)

        assert isinstance(rec, UsageRecord)
        assert rec.model == "gpt-4o"
        assert rec.input_tokens == 1000
        assert rec.output_tokens == 500
        assert rec.cost_usd > 0

    def test_cost_calculation_gpt4o(self) -> None:
        tracker = CostTracker()
        # gpt-4o: $2.50 input, $10.00 output per 1M tokens
        rec = tracker.record("gpt-4o", input_tokens=1_000_000, output_tokens=1_000_000)

        assert rec.cost_usd == 2.50 + 10.00

    def test_cost_calculation_gpt4o_mini(self) -> None:
        tracker = CostTracker()
        # gpt-4o-mini: $0.15 input, $0.60 output per 1M tokens
        rec = tracker.record("gpt-4o-mini", input_tokens=1_000_000, output_tokens=1_000_000)

        assert rec.cost_usd == 0.15 + 0.60

    def test_cost_calculation_claude_sonnet(self) -> None:
        tracker = CostTracker()
        # claude-sonnet-4-6: $3.00 input, $15.00 output per 1M tokens
        rec = tracker.record("claude-sonnet-4-6", input_tokens=500_000, output_tokens=200_000)

        expected = (500_000 * 3.00 + 200_000 * 15.00) / 1_000_000
        assert abs(rec.cost_usd - expected) < 0.0001

    def test_unknown_model_returns_zero_cost(self) -> None:
        tracker = CostTracker()
        rec = tracker.record("unknown-model-x", input_tokens=1000, output_tokens=500)

        assert rec.cost_usd == 0.0

    def test_accumulates_across_calls(self) -> None:
        tracker = CostTracker()
        tracker.record("gpt-4o", input_tokens=1000, output_tokens=200)
        tracker.record("gpt-4o", input_tokens=500, output_tokens=100)
        tracker.record("gpt-4o-mini", input_tokens=2000, output_tokens=500)

        summary = tracker.summary()
        assert summary.calls == 3
        assert summary.total_input_tokens == 3500
        assert summary.total_output_tokens == 800
        assert summary.total_tokens == 4300
        assert summary.total_cost_usd > 0
        assert "gpt-4o" in summary.by_model
        assert "gpt-4o-mini" in summary.by_model

    def test_summary_empty(self) -> None:
        tracker = CostTracker()
        summary = tracker.summary()

        assert summary.calls == 0
        assert summary.total_tokens == 0
        assert summary.total_cost_usd == 0.0

    def test_reset_clears_records(self) -> None:
        tracker = CostTracker()
        tracker.record("gpt-4o", input_tokens=100, output_tokens=50)
        assert len(tracker.records) == 1

        tracker.reset()
        assert len(tracker.records) == 0
        assert tracker.summary().calls == 0

    def test_records_property_returns_copy(self) -> None:
        tracker = CostTracker()
        tracker.record("gpt-4o", input_tokens=100, output_tokens=50)

        records = tracker.records
        records.clear()  # Modifying the copy
        assert len(tracker.records) == 1  # Original unchanged

    def test_by_model_aggregation(self) -> None:
        tracker = CostTracker()
        tracker.record("gpt-4o", input_tokens=1_000_000, output_tokens=0)
        tracker.record("gpt-4o", input_tokens=1_000_000, output_tokens=0)

        summary = tracker.summary()
        # Two calls, each costing $2.50 for input
        assert abs(summary.by_model["gpt-4o"] - 5.00) < 0.0001
