# coding: utf-8
from __future__ import unicode_literals

import re

from .common import InfoExtractor
from ..compat import compat_urlparse
from ..utils import (
    ExtractorError,
    float_or_none,
    int_or_none,
    parse_iso8601,
    try_get,
)


class ArkenaIE(InfoExtractor):
    _VALID_URL = r"""(?x)
                        https?://
                            (?:
                                video\.(?:arkena|qbrick)\.com/play2/embed/player\?|
                                play\.arkena\.com/(?:config|embed)/avp/v\d/player/media/(?P<id>[^/]+)/[^/]+/(?P<account_id>\d+)
                            )
                        """
    _TESTS = [
        {
            "url": "https://video.qbrick.com/play2/embed/player?accountId=1034090&mediaId=d8ab4607-00090107-aab86310",
            "md5": "97f117754e5f3c020f5f26da4a44ebaf",
            "info_dict": {
                "id": "d8ab4607-00090107-aab86310",
                "ext": "mp4",
                "title": "EM_HT20_117_roslund_v2.mp4",
                "timestamp": 1608285912,
                "upload_date": "20201218",
                "duration": 1429.162667,
                "subtitles": {
                    "sv": "count:3",
                },
            },
        },
        {
            "url": "https://play.arkena.com/embed/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411",
            "only_matching": True,
        },
        {
            "url": "https://play.arkena.com/config/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411/?callbackMethod=jQuery1111023664739129262213_1469227693893",
            "only_matching": True,
        },
        {
            "url": "http://play.arkena.com/config/avp/v1/player/media/327336/darkmatter/131064/?callbackMethod=jQuery1111002221189684892677_1469227595972",
            "only_matching": True,
        },
        {
            "url": "http://play.arkena.com/embed/avp/v1/player/media/327336/darkmatter/131064/",
            "only_matching": True,
        },
        {
            "url": "http://video.arkena.com/play2/embed/player?accountId=472718&mediaId=35763b3b-00090078-bf604299&pageStyling=styled",
            "only_matching": True,
        },
    ]

    @staticmethod
    def _extract_url(webpage):
        # See https://support.arkena.com/display/PLAY/Ways+to+embed+your+video
        mobj = re.search(
            r'<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//play\.arkena\.com/embed/avp/.+?)\1',
            webpage,
        )
        if mobj:
            return mobj.group("url")

    def _real_extract(self, url):
        mobj = re.match(self._VALID_URL, url)
        video_id = mobj.group("id")
        account_id = mobj.group("account_id")

        # Handle http://video.arkena.com/play2/embed/player URL
        if not video_id:
            qs = compat_urlparse.parse_qs(compat_urlparse.urlparse(url).query)
            video_id = qs.get("mediaId", [None])[0]
            account_id = qs.get("accountId", [None])[0]
            if not video_id or not account_id:
                raise ExtractorError("Invalid URL", expected=True)

        media = self._download_json(
            "https://video.qbrick.com/api/v1/public/accounts/%s/medias/%s"
            % (account_id, video_id),
            video_id,
            query={
                # https://video.qbrick.com/docs/api/examples/library-api.html
                "fields": "asset/resources/*/renditions/*(height,id,language,links/*(href,mimeType),type,size,videos/*(audios/*(codec,sampleRate),bitrate,codec,duration,height,width),width),created,metadata/*(title,description),tags",
            },
        )
        metadata = media.get("metadata") or {}
        title = metadata["title"]

        duration = None
        formats = []
        thumbnails = []
        subtitles = {}
        for resource in media["asset"]["resources"]:
            for rendition in resource.get("renditions") or []:
                rendition_type = rendition.get("type")
                for i, link in enumerate(rendition.get("links") or []):
                    href = link.get("href")
                    if not href:
                        continue
                    if rendition_type == "image":
                        thumbnails.append(
                            {
                                "filesize": int_or_none(rendition.get("size")),
                                "height": int_or_none(rendition.get("height")),
                                "id": rendition.get("id"),
                                "url": href,
                                "width": int_or_none(rendition.get("width")),
                            }
                        )
                    elif rendition_type == "subtitle":
                        subtitles.setdefault(
                            rendition.get("language") or "en", []
                        ).append(
                            {
                                "url": href,
                            }
                        )
                    elif rendition_type == "video":
                        f = {
                            "filesize": int_or_none(rendition.get("size")),
                            "format_id": rendition.get("id"),
                            "url": href,
                        }
                        video = try_get(rendition, lambda x: x["videos"][i], dict)
                        if video:
                            if not duration:
                                duration = float_or_none(video.get("duration"))
                            f.update(
                                {
                                    "height": int_or_none(video.get("height")),
                                    "tbr": int_or_none(video.get("bitrate"), 1000),
                                    "vcodec": video.get("codec"),
                                    "width": int_or_none(video.get("width")),
                                }
                            )
                            audio = try_get(video, lambda x: x["audios"][0], dict)
                            if audio:
                                f.update(
                                    {
                                        "acodec": audio.get("codec"),
                                        "asr": int_or_none(audio.get("sampleRate")),
                                    }
                                )
                        formats.append(f)
                    elif rendition_type == "index":
                        mime_type = link.get("mimeType")
                        if mime_type == "application/smil+xml":
                            formats.extend(
                                self._extract_smil_formats(href, video_id, fatal=False)
                            )
                        elif mime_type == "application/x-mpegURL":
                            formats.extend(
                                self._extract_m3u8_formats(
                                    href,
                                    video_id,
                                    "mp4",
                                    "m3u8_native",
                                    m3u8_id="hls",
                                    fatal=False,
                                )
                            )
                        elif mime_type == "application/hds+xml":
                            formats.extend(
                                self._extract_f4m_formats(
                                    href, video_id, f4m_id="hds", fatal=False
                                )
                            )
                        elif mime_type == "application/dash+xml":
                            formats.extend(
                                self._extract_f4m_formats(
                                    href, video_id, f4m_id="hds", fatal=False
                                )
                            )
                        elif mime_type == "application/vnd.ms-sstr+xml":
                            formats.extend(
                                self._extract_ism_formats(
                                    href, video_id, ism_id="mss", fatal=False
                                )
                            )
        self._sort_formats(formats)

        return {
            "id": video_id,
            "title": title,
            "description": metadata.get("description"),
            "timestamp": parse_iso8601(media.get("created")),
            "thumbnails": thumbnails,
            "subtitles": subtitles,
            "duration": duration,
            "tags": media.get("tags"),
            "formats": formats,
        }
