"""Tests for crystallise.llm.cost."""

from types import SimpleNamespace

import pytest

from crystallise.llm.cost import estimate_cost, tally_usage


class TestEstimateCost:
    def test_known_model_returns_correct_value(self):
        # gpt-4.1: input=$2.00/1M, output=$8.00/1M
        cost = estimate_cost("gpt-4.1", input_tokens=1_000_000, output_tokens=1_000_000)
        assert cost == pytest.approx(10.0)

    def test_known_model_fractional_tokens(self):
        # gpt-5-mini: input=$0.20/1M, output=$2.00/1M
        cost = estimate_cost("gpt-5-mini", input_tokens=500_000, output_tokens=250_000)
        expected = (500_000 / 1_000_000) * 0.20 + (250_000 / 1_000_000) * 2.00
        assert cost == pytest.approx(expected)

    def test_unknown_model_returns_zero(self):
        cost = estimate_cost("unknown-model-xyz", input_tokens=1000, output_tokens=1000)
        assert cost == 0.0


class TestTallyUsage:
    def test_aggregates_multiple_usage_dicts(self):
        usages = [
            {"input_tokens": 100, "output_tokens": 50, "total_tokens": 150},
            {"input_tokens": 200, "output_tokens": 100, "total_tokens": 300},
        ]
        result = tally_usage("gpt-4.1", usages)
        assert result["input_tokens"] == 300
        assert result["output_tokens"] == 150
        assert result["total_tokens"] == 450
        assert result["estimated_cost_usd"] > 0

    def test_works_with_sdk_objects(self):
        usages = [
            SimpleNamespace(input_tokens=100, output_tokens=50, total_tokens=150),
            SimpleNamespace(input_tokens=200, output_tokens=100, total_tokens=300),
        ]
        result = tally_usage("gpt-4.1", usages)
        assert result["input_tokens"] == 300
        assert result["output_tokens"] == 150
        assert result["total_tokens"] == 450

    def test_empty_list(self):
        result = tally_usage("gpt-4.1", [])
        assert result["input_tokens"] == 0
        assert result["output_tokens"] == 0
        assert result["total_tokens"] == 0
        assert result["estimated_cost_usd"] == 0.0


