"""
$description Israeli live TV channel and video on-demand service owned by Network 13.
$url 13tv.co.il
$type live, vod
$region Israel
"""

import re
from urllib.parse import urljoin, urlunparse

from streamlink.logger import getLogger
from streamlink.plugin import Plugin, PluginError, pluginmatcher
from streamlink.plugin.api import validate
from streamlink.stream.hls import HLSStream


log = getLogger(__name__)


@pluginmatcher(
    re.compile(r"https?://(?:www\.)?13tv\.co\.il/(live|.*?/)"),
)
class N13TV(Plugin):
    api_url = "https://13tv-api.oplayer.io/api/getlink/"
    main_js_url_re = re.compile(r'type="text/javascript" src="(.*?main\..+\.js)"')
    user_id_re = re.compile(r'"data-ccid":"(.*?)"')
    video_name_re = re.compile(r'"videoRef":"(.*?)"')
    server_addr_re = re.compile(r"(.*[^/])(/.*)")
    media_file_re = re.compile(r"(.*)(\.[^\.].*)")

    live_schema = validate.Schema(
        [{"Link": validate.url()}],
        validate.get(0),
        validate.get("Link"),
    )

    vod_schema = validate.Schema(
        [
            {
                "ShowTitle": str,
                "ProtocolType": validate.all(
                    str,
                    validate.transform(lambda x: x.replace("://", "")),
                ),
                "ServerAddress": str,
                "MediaRoot": str,
                "MediaFile": str,
                "Bitrates": str,
                "StreamingType": str,
                "Token": validate.all(
                    str,
                    validate.transform(lambda x: x.lstrip("?")),
                ),
            },
        ],
        validate.get(0),
    )

    def _get_live(self, user_id):
        res = self.session.http.get(
            self.api_url,
            params=dict(
                userId=user_id,
                serverType="web",
                ch=1,
                cdnName="casttime",
            ),
        )

        url = self.session.http.json(res, schema=self.live_schema)
        log.debug(f"URL={url}")

        return HLSStream.parse_variant_playlist(self.session, url)

    def _get_vod(self, user_id, video_name):
        res = self.session.http.get(
            urljoin(self.api_url, "getVideoByFileName"),
            params=dict(
                userId=user_id,
                videoName=video_name,
                serverType="web",
                callback="x",
            ),
        )

        vod_data = self.session.http.json(res, schema=self.vod_schema)

        if video_name == vod_data["ShowTitle"]:
            try:
                host, base_path = self.server_addr_re.search(vod_data["ServerAddress"]).groups()  # type: ignore
            except AttributeError:
                raise PluginError("Could not split 'ServerAddress' components") from None

            try:
                base_file, file_ext = self.media_file_re.search(vod_data["MediaFile"]).groups()  # type: ignore
            except AttributeError:
                raise PluginError("Could not split 'MediaFile' components") from None

            media_path = "".join([
                base_path,
                vod_data["MediaRoot"],
                base_file,
                vod_data["Bitrates"],
                file_ext,
                vod_data["StreamingType"],
            ])
            log.debug("Media path=%s", media_path)

            vod_url = urlunparse((
                vod_data["ProtocolType"],
                host,
                media_path,
                "",
                vod_data["Token"],
                "",
            ))
            log.debug("URL=%s", vod_url)

            return HLSStream.parse_variant_playlist(self.session, vod_url)

    def _get_streams(self):
        url_type = self.match.group(1)
        log.debug(f"URL type={url_type}")

        res = self.session.http.get(self.url)

        if url_type != "live":
            m = self.video_name_re.search(res.text)
            video_name = m and m.group(1)
            if not video_name:
                raise PluginError("Could not determine video_name")
            log.debug(f"Video name={video_name}")

        m = self.main_js_url_re.search(res.text)
        main_js_path = m and m.group(1)
        if not main_js_path:
            raise PluginError("Could not determine main_js_path")
        log.debug(f"Main JS path={main_js_path}")

        res = self.session.http.get(urljoin(self.url, main_js_path))

        m = self.user_id_re.search(res.text)
        user_id = m and m.group(1)
        if not user_id:
            raise PluginError("Could not determine user_id")
        log.debug(f"User ID={user_id}")

        if url_type == "live":
            return self._get_live(user_id)
        else:
            return self._get_vod(user_id, video_name)


__plugin__ = N13TV
