"""/api/bw/me capability booleans are SERVER-DECIDED and correct.

The SPA must never re-derive policy from a level NAME — it consumes these booleans
verbatim. So the tests assert the booleans, never the level string that produced
them. Three actors exercise the seam: the owner (super admin, everything true), a
plain `member` (no permissions, everything false), and an `admin`-level member
(the standard delegated-admin capabilities true, but NOT owner-only ones like
level creation, which the seed admin level does not carry).
"""

from tests.conftest import as_user

# The capability booleans the SPA switches on.
_CAN_FIELDS = [
    "can_manage_accounts", "can_add_accounts", "can_change_levels",
    "can_create_levels", "can_edit_levels", "can_create_instances",
    "can_view_as_others",
]


def _me(client):
    r = client.get("/api/bw/me")
    assert r.status_code == 200
    return r.json()


def test_anonymous_me_has_no_capabilities(client):
    j = _me(client)
    assert j["authenticated"] is False
    assert j["is_owner"] is False
    assert j["is_staff"] is False
    # The anon payload is deliberately minimal — some can_* keys are omitted rather
    # than present-and-false. The invariant is "no capability is granted", so assert
    # that NONE is True (an absent key is correctly falsy for the SPA).
    for field in _CAN_FIELDS:
        assert j.get(field) is not True, field
    assert j["assignable_levels"] == []


def test_owner_me_has_every_capability(client):
    as_user(client, "rian")
    j = _me(client)
    assert j["authenticated"] is True
    assert j["is_owner"] is True
    for field in _CAN_FIELDS:
        assert j[field] is True, field
    assert j["is_staff"] is True
    # The owner may assign every level that exists (the two seed levels here).
    assert set(j["assignable_levels"]) == {"admin", "member"}


def test_plain_member_me_has_no_capabilities(client, kit):
    """A `member` (no permissions) is signed in, but every capability is false and
    it may assign nothing."""
    kit.member("bob", "member")
    as_user(client, "bob")
    j = _me(client)
    assert j["authenticated"] is True
    assert j["is_owner"] is False
    for field in _CAN_FIELDS:
        assert j[field] is False, field
    assert j["assignable_levels"] == []


def test_admin_member_has_delegated_but_not_owner_capabilities(client, kit):
    """An `admin`-level member gets the delegated-admin capabilities (manage/add
    people, change levels, view-as, create instances) — but NOT the owner-tier
    powers the seed admin level does not carry (create/edit levels). Asserted as
    booleans, so the test says nothing about the level's NAME."""
    kit.member("alice", "admin")
    as_user(client, "alice")
    j = _me(client)
    assert j["is_owner"] is False
    # Delegated-admin capabilities the seed admin level grants:
    assert j["can_manage_accounts"] is True
    assert j["can_add_accounts"] is True
    assert j["can_change_levels"] is True
    assert j["can_create_instances"] is True
    assert j["can_view_as_others"] is True
    assert j["is_staff"] is True
    # Owner-tier capabilities the seed admin level does NOT carry:
    assert j["can_create_levels"] is False
    assert j["can_edit_levels"] is False
    # assignable reflects exactly what this actor may hand out.
    assert "member" in j["assignable_levels"]
    assert "admin" not in j["assignable_levels"]
