# tests lobby

from lobby import LobbyManager


def _make():
    return LobbyManager()


def _full_lobby():
    m = _make()
    code = m.create_lobby("c1", "Alice")[0][1]["code"]
    m.join_lobby("c2", "Bob", code)
    m.join_lobby("c3", "Charlie", code)
    m.select_class("c1", "kael")
    m.select_class("c2", "seris")
    m.select_class("c3", "aldric")
    m.set_ready("c1")
    m.set_ready("c2")
    m.set_ready("c3")
    return m, code


def test_create_lobby():
    m = _make()
    msgs = m.create_lobby("c1", "Alice")
    assert msgs[0][1]["type"] == "lobby_created"
    assert len(msgs[0][1]["code"]) == 6


def test_create_lobby_recreate():
    # quand on recree, l'ancien est libere (corrige un bug de "Back" qui bloquait)
    m = _make()
    code1 = m.create_lobby("c1", "Alice")[0][1]["code"]
    msgs = m.create_lobby("c1", "Alice")
    last = next(msg for cid, msg in msgs if cid == "c1" and msg["type"] == "lobby_created")
    assert last["code"] != code1
    assert code1 not in m.lobbies


def test_join_lobby():
    m = _make()
    code = m.create_lobby("c1", "Alice")[0][1]["code"]
    msgs = m.join_lobby("c2", "Bob", code)
    types = {msg["type"] for _, msg in msgs}
    assert "lobby_joined" in types and "player_joined" in types


def test_join_lobby_not_found():
    m = _make()
    msgs = m.join_lobby("c1", "Alice", "XXXXXX")
    assert msgs[0][1]["code"] == "lobby_not_found"


def test_join_lobby_full():
    m = _make()
    code = m.create_lobby("c1", "Alice")[0][1]["code"]
    m.join_lobby("c2", "Bob", code)
    m.join_lobby("c3", "Charlie", code)
    msgs = m.join_lobby("c4", "Dave", code)
    assert msgs[0][1]["code"] == "lobby_full"


def test_class_taken():
    m = _make()
    code = m.create_lobby("c1", "Alice")[0][1]["code"]
    m.join_lobby("c2", "Bob", code)
    m.select_class("c1", "kael")
    msgs = m.select_class("c2", "kael")
    assert msgs[0][1]["code"] == "class_taken"


def test_ready_sans_classe():
    m = _make()
    m.create_lobby("c1", "Alice")
    msgs = m.set_ready("c1")
    assert msgs[0][1]["code"] == "no_class_selected"


def test_start_game_not_host():
    m = _make()
    code = m.create_lobby("c1", "Alice")[0][1]["code"]
    m.join_lobby("c2", "Bob", code)
    msgs = m.start_game("c2")
    assert msgs[0][1]["code"] == "not_host"


def test_start_game_ok():
    m, _ = _full_lobby()
    msgs = m.start_game("c1")
    assert len(msgs) == 3
    assert all(msg["type"] == "game_starting" for _, msg in msgs)


def test_disconnect_transfere_host():
    m = _make()
    code = m.create_lobby("c1", "Alice")[0][1]["code"]
    m.join_lobby("c2", "Bob", code)
    m.disconnect("c1")
    assert m.lobbies[code].players[0].is_host is True
