"""
$description Live TV channels and video on-demand service from ZDF, a German public, independent broadcaster.
$url zdf.de
$type live, vod
$region Germany
"""

import re
from urllib.parse import urlparse, urlunparse

from streamlink.logger import getLogger
from streamlink.plugin import Plugin, pluginmatcher
from streamlink.plugin.api import validate
from streamlink.stream.hls import HLSStream
from streamlink.utils.url import url_concat


log = getLogger(__name__)


@pluginmatcher(
    re.compile(r"https?://(\w+\.)?(zdf\.de|3sat\.de)/"),
)
class ZDFMediathek(Plugin):
    PLAYER_ID = "ngplayer_2_4"

    def _get_streams(self):
        zdf_json = self.session.http.get(
            self.url,
            schema=validate.Schema(
                validate.parse_html(),
                validate.xml_xpath_string(".//*[@data-zdfplayer-jsb][1]/@data-zdfplayer-jsb"),
                validate.none_or_all(
                    validate.parse_json(),
                    {
                        "apiToken": str,
                        "content": validate.url(),
                    },
                    validate.union_get("apiToken", "content"),
                ),
            ),
        )
        if zdf_json is None:
            return

        apiToken, apiUrl = zdf_json

        headers = {
            "Accept": "application/vnd.de.zdf.v1.0+json;charset=UTF-8",
            "Api-Auth": f"Bearer {apiToken}",
            "Referer": self.url,
        }

        pApiUrl = urlparse(apiUrl)
        apiUrlBase = urlunparse((pApiUrl.scheme, pApiUrl.netloc, "", "", "", ""))
        apiUrlPath = self.session.http.get(
            apiUrl,
            headers=headers,
            schema=validate.Schema(
                validate.parse_json(),
                {
                    "mainVideoContent": {
                        "http://zdf.de/rels/target": {
                            "http://zdf.de/rels/streams/ptmd-template": str,
                        },
                    },
                },
                validate.get(("mainVideoContent", "http://zdf.de/rels/target", "http://zdf.de/rels/streams/ptmd-template")),
                validate.transform(lambda template: template.format(playerId=self.PLAYER_ID).replace(" ", "")),
            ),
        )

        stream_request_url = url_concat(apiUrlBase, apiUrlPath)
        data = self.session.http.get(
            stream_request_url,
            headers=headers,
            schema=validate.Schema(
                validate.parse_json(),
                {
                    "priorityList": [
                        {
                            "formitaeten": validate.all(
                                [
                                    {
                                        "type": str,
                                        "qualities": validate.all(
                                            [
                                                {
                                                    "quality": str,
                                                    "audio": {
                                                        "tracks": [
                                                            {
                                                                "uri": validate.url(),
                                                            },
                                                        ],
                                                    },
                                                },
                                            ],
                                            validate.filter(lambda obj: obj["quality"] == "auto"),
                                        ),
                                    },
                                ],
                                validate.filter(lambda obj: obj["type"] == "h264_aac_ts_http_m3u8_http"),
                            ),
                        },
                    ],
                },
                validate.get("priorityList"),
            ),
        )

        for priority in data:
            for formitaeten in priority["formitaeten"]:
                for quality in formitaeten["qualities"]:
                    for audio in quality["audio"]["tracks"]:
                        yield from HLSStream.parse_variant_playlist(self.session, audio["uri"], headers=headers).items()


__plugin__ = ZDFMediathek
