"""
$description Turkish web conferencing platform.
$url web.tv
$type live
"""

import base64
import binascii
import logging
import re

from streamlink.plugin import Plugin, pluginmatcher
from streamlink.plugin.api import validate
from streamlink.stream.hls import HLSStream
from streamlink.utils.crypto import AES, unpad_pkcs5
from streamlink.utils.parse import parse_json
from streamlink.utils.url import update_scheme


log = logging.getLogger(__name__)


@pluginmatcher(re.compile(
    r"https?://(\w+)\.web\.tv/?",
))
class WebTV(Plugin):
    _sources_re = re.compile(r'"sources": (\[.*?\]),', re.DOTALL)

    @staticmethod
    def decrypt_stream_url(encoded_url):
        data = base64.b64decode(encoded_url)
        cipher_text = binascii.unhexlify(data[96:])

        decryptor = AES.new(binascii.unhexlify(data[32:96]),
                            AES.MODE_CBC,
                            binascii.unhexlify(data[:32]))

        return unpad_pkcs5(decryptor.decrypt(cipher_text)).decode("utf8")

    def _get_streams(self):
        """
        Find the streams for web.tv
        :return:
        """
        headers = {}
        res = self.session.http.get(self.url, headers=headers)
        headers["Referer"] = self.url

        sources = self._sources_re.findall(res.text)
        if not len(sources):
            return

        sdata = parse_json(sources[0], schema=validate.Schema([
            {
                "src": validate.any(
                    validate.contains("m3u8"),
                    validate.all(
                        str,
                        validate.transform(self.decrypt_stream_url),
                        validate.contains("m3u8"),
                    ),
                ),
                "type": str,
                "label": str,
            },
        ]))
        for source in sdata:
            log.debug(f"Found stream of type: {source['type']}")
            if source["type"] == "application/vnd.apple.mpegurl":
                url = update_scheme("https://", source["src"], force=False)

                try:
                    # try to parse the stream as a variant playlist
                    variant = HLSStream.parse_variant_playlist(self.session, url, headers=headers)
                    if variant:
                        yield from variant.items()
                    else:
                        # and if that fails, try it as a plain HLS stream
                        yield "live", HLSStream(self.session, url, headers=headers)
                except OSError:
                    log.warning("Could not open the stream, perhaps the channel is offline")


__plugin__ = WebTV
