from twisted.words.xish import domish
from twisted.words.protocols.jabber import jid
from libervia.backend.plugins.plugin_xep_0298 import NS_COIN, NS_CONFERENCE_INFO, XEP_0298
from libervia.backend.core.constants import Const as C


class TestXEP0298:
    def test_add_conference_info(self, host):
        """Conference info element is correctly added to jingle element"""
        xep_0298 = XEP_0298(host)
        jingle_elt = domish.Element((None, "jingle"))

        conference_info_elt = xep_0298.add_conference_info(
            jingle_elt, is_focus=True, room="test_room"
        )

        assert conference_info_elt.name == "conference-info"
        assert conference_info_elt.uri == NS_CONFERENCE_INFO
        assert conference_info_elt["isfocus"] == C.BOOL_TRUE
        assert conference_info_elt["room"] == "test_room"

    def test_add_user(self, host):
        """User is correctly added to conference info element"""
        xep_0298 = XEP_0298(host)
        conference_info_elt = domish.Element((NS_CONFERENCE_INFO, "conference-info"))
        entity = jid.JID("user@example.com/resource")

        user_elt = xep_0298.add_user(conference_info_elt, entity)

        assert user_elt.name == "user"
        assert user_elt.parent.name == "users"
        assert user_elt["entity"] == "xmpp:user%40example.com"

    def test_add_multiple_users(self, host):
        """Multiple users are correctly added to conference info element"""
        xep_0298 = XEP_0298(host)
        conference_info_elt = domish.Element((NS_CONFERENCE_INFO, "conference-info"))
        entities = [jid.JID(f"user{i}@example.com/resource") for i in range(3)]

        for entity in entities:
            xep_0298.add_user(conference_info_elt, entity)

        users_elt = next(conference_info_elt.elements(NS_CONFERENCE_INFO, "users"))
        user_elts = list(users_elt.elements(NS_CONFERENCE_INFO, "user"))
        assert len(user_elts) == 3
        for i, user_elt in enumerate(user_elts):
            assert user_elt["entity"] == f"xmpp:user{i}%40example.com"

    def test_parse_with_conference_info(self, host):
        """Jingle element with conference info is correctly parsed"""
        xep_0298 = XEP_0298(host)
        jingle_elt = domish.Element((None, "jingle"))
        conference_info_elt = jingle_elt.addElement(
            (NS_CONFERENCE_INFO, "conference-info")
        )
        users_elt = conference_info_elt.addElement("users")
        user_elt = users_elt.addElement("user")
        user_elt["entity"] = "xmpp:user%40example.com"

        result = xep_0298.parse(jingle_elt)

        assert "info" in result
        assert "users" in result["info"]
        assert len(result["info"]["users"]) == 1
        assert str(result["info"]["users"][0]) == "user@example.com"

    def test_parse_without_conference_info(self, host):
        """Jingle element without conference info returns empty dict"""
        xep_0298 = XEP_0298(host)
        jingle_elt = domish.Element((None, "jingle"))

        result = xep_0298.parse(jingle_elt)

        assert result == {}

    def test_coin_handler_disco_info(self, host):
        """CoinHandler returns correct disco info"""
        xep_0298 = XEP_0298(host)
        handler = xep_0298.get_handler(None)

        disco_info = handler.getDiscoInfo(None, None)

        assert len(disco_info) == 1
        assert disco_info[0] == NS_COIN
