import pytest

from promrs import CollectorRegistry, Counter, generate_latest


def test_counter_inc() -> None:
    registry = CollectorRegistry()
    c = Counter("requests", "Total requests", ["method"], registry=registry)
    child = c.labels(method="GET")
    child.inc()
    child.inc()
    output = generate_latest(registry).decode()
    assert 'requests_total{method="GET"} 2.0' in output


def test_counter_inc_by() -> None:
    registry = CollectorRegistry()
    c = Counter("bytes", "Total bytes", ["direction"], registry=registry)
    c.labels(direction="in").inc(100.5)
    output = generate_latest(registry).decode()
    assert 'bytes_total{direction="in"} 100.5' in output


def test_counter_multiple_labels() -> None:
    registry = CollectorRegistry()
    c = Counter("http_requests", "HTTP requests", ["method", "endpoint"], registry=registry)
    c.labels(method="GET", endpoint="/api").inc()
    c.labels(method="POST", endpoint="/api").inc(5.0)
    output = generate_latest(registry).decode()
    assert 'http_requests_total{endpoint="/api",method="GET"} 1.0' in output
    assert 'http_requests_total{endpoint="/api",method="POST"} 5.0' in output


def test_counter_negative_increment_raises() -> None:
    registry = CollectorRegistry()
    c = Counter("test_counter", "test", ["l"], registry=registry)
    with pytest.raises(ValueError, match="non-negative"):
        c.labels(l="v").inc(-1.0)


def test_counter_wrong_labels_raises() -> None:
    registry = CollectorRegistry()
    c = Counter("test_counter", "test", ["method"], registry=registry)
    with pytest.raises(ValueError, match="Missing label"):
        c.labels(wrong="value")


def test_counter_extra_labels_raises() -> None:
    registry = CollectorRegistry()
    c = Counter("test_counter", "test", ["method"], registry=registry)
    with pytest.raises(ValueError, match="Expected"):
        c.labels(method="GET", extra="value")


def test_counter_same_labels_share_state() -> None:
    registry = CollectorRegistry()
    c = Counter("shared", "test", ["k"], registry=registry)
    c.labels(k="v").inc()
    c.labels(k="v").inc()
    output = generate_latest(registry).decode()
    assert 'shared_total{k="v"} 2.0' in output
