#!/usr/bin/env python3

# Libervia: an XMPP client
# Copyright (C) 2009-2026 Jérôme Poisson (goffi@goffi.org)

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


from twisted.words.xish import domish

from libervia.backend.plugins.plugin_xep_0338 import NS_JINGLE_GROUPING, XEP_0338
from libervia.backend.tools.xml_tools import parse


class TestXEP0338:
    def test_parse_sdp(self, host):
        """'group' attribute in SDP is correctly parsed"""
        xep_0338 = XEP_0338(host)

        call_data = {}
        metadata = {}
        media_type = "video"
        application_data = {}
        transport_data = {}

        # SDP: a=group:BUNDLE audio video
        attribute = "group"
        parts = ["BUNDLE", "audio", "video"]

        xep_0338._parse_sdp_a_trigger(
            attribute,
            parts,
            call_data,
            metadata,
            media_type,
            application_data,
            transport_data,
        )

        assert metadata == {"group": {"BUNDLE": ["audio", "video"]}}

    def test_generate_sdp(self, host):
        """'group' attribute in SDP is correctly generated"""
        xep_0338 = XEP_0338(host)

        session = {"metadata": {"group": {"BUNDLE": ["audio", "video"]}}}
        sdp_lines = []
        local = True

        xep_0338._generate_sdp_session_trigger(session, local, sdp_lines)

        assert sdp_lines == ["a=group:BUNDLE audio video"]

    def test_group_building(self, host, client):
        """<group> element are built from session in session init trigger"""
        xep_0338 = XEP_0338(host)

        session = {
            "contents": {"audio": {}},
            "jingle_elt": domish.Element((None, "jingle")),
            "metadata": {"group": {"BUNDLE": ["audio", "video"]}},
        }
        content_name = "audio"
        media = "audio"
        media_data = {}
        desc_elt = domish.Element((None, "description"))

        xep_0338._jingle_session_init_trigger(
            client, session, content_name, media, media_data, desc_elt
        )

        group_elts = list(session["jingle_elt"].elements(NS_JINGLE_GROUPING, "group"))
        assert len(group_elts) == 1
        group_elt = group_elts[0]
        assert group_elt["semantics"] == "BUNDLE"
        content_names = [
            content_elt["name"]
            for content_elt in group_elt.elements(NS_JINGLE_GROUPING, "content")
        ]
        assert content_names == ["audio", "video"]

    async def test_group_parsing(self, host, client):
        """<group> elements are correctly parsed in jingle_handler trigger"""
        xep_0338 = XEP_0338(host)

        action = xep_0338._j.A_SESSION_INITIATE
        session = {
            "contents": ["audio", "video"],
            "metadata": {},
        }

        raw_xml = """
        <jingle xmlns='urn:xmpp:jingle:1'
                action='session-initiate'
                initiator='user@example.org/orchard'
                sid='a73sjjvkla37jfea'>
          <group xmlns='urn:xmpp:jingle:apps:grouping:0' semantics='BUNDLE'>
            <content name='audio'/>
            <content name='video'/>
          </group>
          <content creator='initiator' name='audio'>
              <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'/>
          </content>
          <content creator='initiator' name='video'>
              <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'/>
          </content>
        </jingle>
        """
        session["jingle_elt"] = parse(raw_xml)

        for content_elt in session["jingle_elt"].elements("urn:xmpp:jingle:1", "content"):
            content_name = content_elt["name"]
            desc_elt = next(
                content_elt.elements("urn:xmpp:jingle:apps:rtp:1", "description")
            )

            await xep_0338._jingle_handler_trigger(
                client, action, session, content_name, desc_elt
            )

        group_elts = list(session["jingle_elt"].elements(NS_JINGLE_GROUPING, "group"))
        assert len(group_elts) == 1
        group_elt = group_elts[0]
        assert group_elt["semantics"] == "BUNDLE"
        content_names = [
            content_elt["name"]
            for content_elt in group_elt.elements(NS_JINGLE_GROUPING, "content")
        ]
        assert content_names == ["audio", "video"]
