import json
from time import sleep, strftime, localtime, time
import logging
import re

from config import config
from daemon import VideoDaemon
from tools import get, Database, while_warp
from video_process import process_video

logger = logging.getLogger('run.youtube')


class Youtube(VideoDaemon):

    def __init__(self, user_config):
        super().__init__(user_config)
        self.module = 'Youtube'
        self.api_key = config['youtube']['api_key']

    @staticmethod
    def get_video_info_by_html(url):
        """
        The method is using yfconfig to get information of video including title, video_id, data and thumbnail
        :rtype: dict
        """
        video_page = get(url)
        try:
            ytplayer_config = json.loads(re.search(r'ytplayer.config\s*=\s*([^\n]+?});', video_page).group(1))
            player_response = json.loads(ytplayer_config['args']['player_response'])
            video_details = player_response['videoDetails']
            # assert to verity live status
            if 'isLive' not in video_details:
                is_live = False
            else:
                is_live = True
            title = video_details['title']
            vid = video_details['videoId']
            target = f"https://www.youtube.com/watch?v={vid}"
            thumbnails = video_details['thumbnail']['thumbnails'][-1]['url']
            return {'Title': title,
                    'Ref': vid,
                    'Date': strftime("%Y-%m-%d", localtime(time())),
                    'Target': target,
                    'Thumbnails': thumbnails,
                    'User': video_details['channelId'],
                    'Is_live': is_live}
        except KeyError:
            logger.exception('Get keys error')
            return False

    @while_warp
    def check(self):
        try:
            video_dict = self.get_video_info_by_html(f'https://www.youtube.com/channel/{self.target_id}/live')
            if video_dict['Is_live']:
                video_dict['Provide'] = self.module
                process_video(video_dict, self.user_config)
            else:
                logger.info(f'{self.target_id}: Not found Live')
        except Exception:
            logger.exception('Check Failed')


class YoutubeTemp(Youtube):
    def __init__(self, vinfo):
        super().__init__(None)
        self.vinfo = vinfo
        self.db = Database('Queues')

    @staticmethod
    def get_temp_vid(vlink):
        reg = r"watch\?v=([A-Za-z0-9_-]{11})"
        idre = re.compile(reg)
        _id = vlink["_id"]
        vid = vlink["Link"]
        vid = re.search(idre, vid).group(1)
        return {'Vid': vid,
                'Id': _id}

    def check(self):
        self.vinfo = self.get_temp_vid(self.vinfo)
        vid = self.vinfo['Vid']
        _id = self.vinfo['Id']
        video_dict = self.get_video_info_by_html(f"https://www.youtube.com/watch?v={vid}")
        if video_dict['Is_live']:
            video_dict['Provide'] = self.module
            user_config = {
                'bot_notice': config['youtube']['enable_temp_bot_notice'],
                'download': config['youtube']['enable_temp_download']
            }
            process_video(video_dict, user_config)
            self.db.delete(_id)
        else:
            logger.info(f'Not found Live')

    def run(self) -> None:
        self.check()


def start_temp_daemon():
    db = Database('Queues')
    while True:
        event = []
        for target_url in db.select():
            p = YoutubeTemp(target_url)
            event.append(p)
            p.daemon = True
            p.start()
        is_running = True
        while is_running:
            has_running = False
            for p in event:
                if p.is_alive():
                    has_running = True
            if not has_running:
                is_running = False
        logger.info('A check has finished.')
        sleep(config['sec'])