from __future__ import annotations

from decimal import Decimal

import pytest

from core.agent.cost_tracker import CostTracker


def test_normalize_usage_and_cost_aggregation() -> None:
    tracker = CostTracker()

    tracker.add_usage(
        {
            "prompt_tokens": 7,
            "completion_tokens": 5,
            "cost": "0.002500",
        }
    )
    tracker.add_usage(
        {
            "input_tokens": 5,
            "output_tokens": 3,
            "cost": "0.003000",
            "currency": "USD",
        }
    )

    snapshot = tracker.snapshot()

    assert snapshot["input_tokens"] == 12
    assert snapshot["output_tokens"] == 8
    assert snapshot["total_tokens"] == 20
    assert snapshot["cost"] == Decimal("0.005500")
    assert snapshot["currency"] == "USD"


def test_add_usage_rejects_negative_values() -> None:
    tracker = CostTracker()

    with pytest.raises(ValueError):
        tracker.add_usage({"input_tokens": -1})

    with pytest.raises(ValueError):
        tracker.add_usage({"cost": "-0.010000"})


def test_snapshot_is_zero_before_any_usage() -> None:
    tracker = CostTracker()

    snapshot = tracker.snapshot()

    assert snapshot["input_tokens"] == 0
    assert snapshot["output_tokens"] == 0
    assert snapshot["total_tokens"] == 0
    assert snapshot["cost"] == Decimal("0")
    assert snapshot["currency"] == "USD"


def test_add_usage_rejects_currency_mismatch() -> None:
    tracker = CostTracker(currency="USD")
    tracker.add_usage({"input_tokens": 1, "output_tokens": 1, "cost": "0.001000"})

    with pytest.raises(ValueError):
        tracker.add_usage(
            {
                "input_tokens": 1,
                "output_tokens": 1,
                "cost": "0.001000",
                "currency": "CNY",
            }
        )


def test_add_usage_rejects_non_integral_token_values() -> None:
    tracker = CostTracker()

    with pytest.raises(ValueError):
        tracker.add_usage({"input_tokens": 1.5})

    with pytest.raises(ValueError):
        tracker.add_usage({"output_tokens": True})
