from spider import Spider, SpiderItemType, SpiderSource, SpiderDanmaku, SpiderItem, SpiderPlayURL
from proxy import get_proxy_url
from urllib.parse import urlparse
from danmaku import get_danmaku_url
from utils import get_image_path
import requests
import hashlib
import time
import xbmcaddon

_ADDON = xbmcaddon.Addon()

base_params = {
    'pcode': '010110005',
    'version': '2.1.2',
    'devid': hashlib.md5(str(time.time()).encode()).hexdigest(),
    'sys': 'android',
    'sysver': 12,
    'brand': 'Redmi',
    'model': 'M2104K10AC',
    'package': 'android.bugly.qq.com'
}

base_headers = {
    'User-Agent': 'okhttp/3.12.0',
}


class Spider77(Spider):

    def name(self):
        return '七七'

    def logo(self):
        return get_image_path('qiqi.png')

    def hide(self):
        return not _ADDON.getSettingBool('data_source_77_switch')

    def is_searchable(self):
        return True

    def list_items(self, parent_item=None, page=1):
        if parent_item is None:
            r = requests.get('http://api.kunyu77.com/api.php/provide/filter',
                             headers=base_headers.copy())
            data = r.json()
            items = []
            for id in data['data']:
                name = data['data'][id][0]['cat']
                items.append(
                    SpiderItem(
                        type=SpiderItemType.Directory,
                        name=name,
                        id=id,
                        params={
                            'type': 'category',
                        },
                    ))
            return items, False
        elif parent_item['params']['type'] == 'category':
            r = requests.get(
                'http://api.kunyu77.com/api.php/provide/searchFilter',
                params={
                    'type_id': parent_item['id'],
                    'pagenum': page,
                    'pagesize': 50
                },
                headers=base_headers.copy())
            data = r.json()
            items = []
            for video in data['data']['result']:
                items.append(
                    SpiderItem(
                        type=SpiderItemType.Directory,
                        name=video['title'],
                        id=video['id'],
                        cover=video['videoCover'],
                        params={
                            'type': 'video',
                        },
                    ))

            has_next_page = page < data['data']['pagesize']
            return items, has_next_page
        elif parent_item['params']['type'] == 'video':
            ts = int(time.time())
            params = base_params.copy()
            params['ids'] = parent_item['id']
            params['sj'] = ts

            headers = base_headers.copy()
            headers['t'] = str(ts)

            url = 'http://api.kunyu77.com/api.php/provide/videoDetail'
            headers['TK'] = self._get_tk(url, params, ts)
            r = requests.get(url, params=params, headers=headers)
            detail = r.json()['data']

            url = 'http://api.kunyu77.com/api.php/provide/videoPlaylist'
            headers['TK'] = self._get_tk(url, params, ts)
            r = requests.get(url, params=params, headers=headers)
            episodes = r.json()['data']['episodes']

            items = []
            for episode in episodes:
                sources = []
                danmakus = []
                for playurl in episode['playurls']:
                    sources.append(
                        SpiderSource(
                            playurl['playfrom'],
                            {
                                'playfrom': playurl['playfrom'],
                                'url': playurl['playurl'],
                            },
                        ))

                    if playurl['playfrom'] in [
                            'qq', 'mgtv', 'qiyi', 'youku', 'bilibili'
                    ]:
                        danmakus.append(
                            SpiderDanmaku(
                                playurl['playfrom'],
                                get_danmaku_url(playurl['playurl']),
                            ))

                items.append(
                    SpiderItem(
                        type=SpiderItemType.File,
                        name=episode['title'],
                        cover=detail['videoCover'],
                        description=detail['brief'],
                        cast=detail['actor'].split(' '),
                        director=detail['director'],
                        area=detail['area'],
                        year=int(detail['year']),
                        sources=sources,
                        danmakus=danmakus,
                    ))
            return items, False

        else:
            return [], False

    def resolve_play_url(self, source_params):
        url = source_params['url']
        headers = {}

        if source_params['playfrom'] != 'ppayun':
            r = requests.get(
                'http://api.kunyu77.com/api.php/provide/parserUrl',
                params={'url': source_params['url']},
                headers=base_headers.copy())
            data = r.json()['data']
            if 'playHeader' in data:
                for key in data['playHeader']:
                    headers[key] = data['playHeader'][key]

            r = requests.get(data['url'])
            url = r.json()['url']

        return SpiderPlayURL(
            get_proxy_url(
                Spider77.__name__,
                self.proxy_m3u8.__name__,
                {
                    'url': url,
                    'headers': headers,
                },
            ))

    def search(self, keyword):
        url = 'http://api.kunyu77.com/api.php/provide/searchVideo'

        ts = int(time.time())
        params = base_params.copy()
        params['sj'] = ts
        params['searchName'] = keyword
        params['pg'] = 1

        headers = base_headers.copy()
        headers['t'] = str(ts)
        headers['TK'] = self._get_tk(url, params, ts)

        r = requests.get(url, params=params, headers=headers)
        data = r.json()
        items = []
        for video in data['data']:
            items.append(
                SpiderItem(
                    type=SpiderItemType.Directory,
                    name=video['videoName'],
                    id=video['id'],
                    cover=video['videoCover'],
                    description=video['brief'],
                    cast=video['starName'].split(','),
                    year=int(video['year']),
                    params={
                        'type': 'video',
                    },
                ))
        return items

    def _get_tk(self, url, params, ts):
        keys = []
        for key in params:
            keys.append(key)
        keys.sort()

        src = urlparse(url).path
        for key in keys:
            src += str(params[key])
        src += str(ts)
        src += 'XSpeUFjJ'

        return hashlib.md5(src.encode()).hexdigest()

    def proxy_m3u8(self, ctx, params):
        url = params['url']
        headers = params['headers'].copy()

        r = requests.get(url, headers=headers, stream=True, verify=False)

        content_type = r.headers[
            'Content-Type'] if 'Content-Type' in r.headers else ''
        if content_type.startswith('image/') or content_type.startswith(
                'text/'):
            content_type = 'application/vnd.apple.mpegurl'
        r.headers['Content-Type'] = content_type

        try:
            ctx.send_response(r.status_code)
            for key in r.headers:
                if key.lower() in [
                        'connection',
                        'transfer-encoding',
                ]:
                    continue
                if content_type.lower() == 'application/vnd.apple.mpegurl':
                    if key.lower() in [
                            'content-length',
                            'content-range',
                    ]:
                        continue
                ctx.send_header(key, r.headers[key])
            ctx.end_headers()

            if content_type.lower() == 'application/vnd.apple.mpegurl':
                for line in r.iter_lines(8192):
                    line = line.decode()
                    if len(line) > 0 and not line.startswith('#'):
                        if not line.startswith('http'):
                            if line.startswith('/'):
                                line = url[:url.index('/', 8)] + line
                            else:
                                line = url[:url.rindex('/') + 1] + line
                        line = get_proxy_url(
                            Spider77.__name__,
                            self.proxy_ts.__name__,
                            {
                                'url': line,
                                'headers': params['headers'],
                            },
                        )
                    ctx.wfile.write((line + '\n').encode())
            else:
                for chunk in r.iter_content(8192):
                    ctx.wfile.write(chunk)
        except Exception as e:
            print(e)
        finally:
            try:
                r.close()
            except:
                pass

    def proxy_ts(self, ctx, params):
        url = params['url']
        headers = params['headers'].copy()

        for key in ctx.headers:
            if key.lower() in [
                    'user-agent',
                    'host',
            ]:
                continue
            headers[key] = ctx.headers[key]
        r = requests.get(url, headers=headers, stream=True, verify=False)
        r.headers['Content-Type'] = 'video/MP2T'

        try:
            ctx.send_response(r.status_code)
            for key in r.headers:
                if key.lower() in [
                        'connection',
                        'transfer-encoding',
                        'accept-ranges',
                ]:
                    continue
                ctx.send_header(key, r.headers[key])
            ctx.end_headers()

            stripped_image_header = False
            for chunk in r.iter_content(8192):
                if not stripped_image_header:
                    chunk = chunk.lstrip(b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A')
                    stripped_image_header = True
                ctx.wfile.write(chunk)
        except Exception as e:
            print(e)
        finally:
            try:
                r.close()
            except:
                pass
