"""Tests for token scope hierarchy + back-compat with legacy bare-string tokens."""

from __future__ import annotations

import pytest

from media_server.config import Settings, TokenSpec


def test_bare_string_token_promotes_to_admin_scope():
    """Legacy `label: <token>` form must still work and grant admin."""
    s = Settings(api_tokens={"legacy": "deadbeef-deadbeef-deadbeef-deadbeef"})
    spec = s.api_tokens["legacy"]
    assert isinstance(spec, TokenSpec)
    assert spec.token == "deadbeef-deadbeef-deadbeef-deadbeef"
    assert spec.scopes == ["admin"]
    assert spec.grants("admin")
    assert spec.grants("control")
    assert spec.grants("read")


def test_dict_token_with_explicit_scopes():
    s = Settings(api_tokens={
        "ha": {"token": "aaaaaaaaaaaaaaaa", "scopes": ["read", "control"]},
    })
    spec = s.api_tokens["ha"]
    assert spec.grants("control")
    assert spec.grants("read")
    assert not spec.grants("admin")


def test_read_only_scope_grants_only_read():
    spec = TokenSpec(token="xxxxxxxxxxxxxxxx", scopes=["read"])
    assert spec.grants("read")
    assert not spec.grants("control")
    assert not spec.grants("admin")


def test_admin_scope_implies_control_and_read():
    spec = TokenSpec(token="xxxxxxxxxxxxxxxx", scopes=["admin"])
    assert spec.grants("read")
    assert spec.grants("control")
    assert spec.grants("admin")


def test_unknown_scope_rejected():
    with pytest.raises(ValueError, match="unknown scopes"):
        TokenSpec(token="xxxxxxxxxxxxxxxx", scopes=["root"])


def test_empty_scopes_rejected():
    with pytest.raises(ValueError, match="at least one"):
        TokenSpec(token="xxxxxxxxxxxxxxxx", scopes=[])


def test_short_token_rejected():
    with pytest.raises(ValueError):
        TokenSpec(token="short", scopes=["read"])
