import threading
from . import nyaa, gogoanime, animixplay, debrid_cloudfiles
from ..ui.globals import g
from resources.lib.windows.get_sources_window import GetSources as DisplayWindow
import time

class CancelProcess(Exception):
    pass


def getSourcesHelper(actionArgs):
##    sources_window = Sources(*SkinManager().confirm_skin_path('get_sources.xml'),
##                             actionArgs=actionArgs)

    sources_window = Sources(*('get_sources.xml', g.ADDON_DATA_PATH),
                             actionArgs=actionArgs)

    sources = sources_window.doModal()
    try:
        del sources_window
    except:
        pass
    return sources

class Sources(DisplayWindow):
    def __init__(self, xml_file, location, actionArgs=None):
        try:
            super(Sources, self).__init__(xml_file, location, actionArgs)
        except:
            self.args = actionArgs
            self.canceled = False

        self.torrent_threads = []
        self.hoster_threads = []
        self.torrentProviders = []
        self.hosterProviders = []
        self.language = 'en'
        self.torrentCacheSources = []
        self.embedSources = []
        self.hosterSources = []
        self.cloud_files = []
        self.remainingProviders = ['nyaa', 'gogo']
        self.allTorrents = {}
        self.allTorrents_len = 0
        self.hosterDomains = {}
        self.torrents_qual_len = [0, 0, 0, 0]
        self.hosters_qual_len = [0, 0, 0, 0]
        self.trakt_id = ''
        self.silent = False
        self.return_data = (None, None, None)
        self.basic_windows = True
        self.progress = 1
        self.duplicates_amount = 0
        self.domain_list = []
        self.display_style = 0
        self.background_dialog = None
        self.running_providers = []

        self.line1 = ''
        self.line2 = ''
        self.line3 = ''

        self.host_domains = []
        self.host_names = []

        self.remainingSources = ['1', '2', '3']
        self.nyaaSources = []
        self.gogoSources = []
        self.animixplaySources = []
        self.threads = []

    def getSources(self, args):
        query = args['query']
        anilist_id = args['anilist_id']
        episode = args['episode']
        status = args['status']
        filter_lang = args['filter_lang']
        media_type = args['media_type']
        rescrape = args['rescrape']
        get_backup = args['get_backup']
        self.setProperty('process_started', 'true')

        if g.real_debrid_enabled() or g.all_debrid_enabled() or g.premiumize_enabled():
            self.threads.append(
                threading.Thread(target=self.nyaa_worker, args=(query, anilist_id, episode, status, media_type, rescrape,)))
        else:
            self.remainingProviders.remove('nyaa')

        self.threads.append(
            threading.Thread(target=self.gogo_worker, args=(anilist_id, episode, get_backup, rescrape,)))

##        self.threads.append(
##            threading.Thread(target=self.animixplay_worker, args=(anilist_id, episode, get_backup, rescrape,)))

        self.threads.append(
            threading.Thread(target=self.user_cloud_inspection, args=(query, anilist_id, episode, media_type, rescrape,)))

        for i in self.threads:
            i.start()

        timeout = 60
        start_time = time.time()
        runtime = 0

        while self.progress < 100:
            if (len(self.remainingProviders) == 0 and runtime > 5):
                break

            if self.canceled:
                break

            try:
                self.updateProgress()
            except:
                pass

            try:
                self.setProgress()
                self.setText("4K: %s | 1080: %s | 720: %s | SD: %s" % (
                    g.color_string(self.torrents_qual_len[0] + self.hosters_qual_len[0]),
                    g.color_string(self.torrents_qual_len[1] + self.hosters_qual_len[1]),
                    g.color_string(self.torrents_qual_len[2] + self.hosters_qual_len[2]),
                    g.color_string(self.torrents_qual_len[3] + self.hosters_qual_len[3]),
                ))

            except:
                import traceback
                traceback.print_exc()

            # Update Progress
            time.sleep(.200)
            runtime = time.time() - start_time
            self.progress = int(100 - float(1 - (runtime / float(timeout))) * 100)
    
        if len(self.torrentCacheSources) + len(self.embedSources) + len(self.cloud_files) == 0:
            self.return_data = []
            self.close()
            return

        sourcesList = self.sortSources(self.torrentCacheSources, self.embedSources, filter_lang)
        self.return_data = sourcesList
        self.close()
        return

    def nyaa_worker(self, query, anilist_id, episode, status, media_type, rescrape):
        self.nyaaSources = nyaa.sources().get_sources(query, anilist_id, episode, status, media_type, rescrape)
        self.torrentCacheSources += self.nyaaSources
        self.remainingProviders.remove('nyaa')        

    def gogo_worker(self, anilist_id, episode, get_backup, rescrape):
        if not rescrape:
            self.gogoSources = gogoanime.sources().get_sources(anilist_id, episode, get_backup)
            self.embedSources += self.gogoSources

        self.remainingProviders.remove('gogo')        

    def animixplay_worker(self, anilist_id, episode, get_backup, rescrape):
        if not rescrape:
            self.animixplaySources = animixplay.sources().get_sources(anilist_id, episode, get_backup)
            self.embedSources += self.animixplaySources

        self.remainingProviders.remove('animixplay')

    def user_cloud_inspection(self, query, anilist_id, episode, media_type, rescrape):
        self.remainingProviders.append('Cloud Inspection')

        if not rescrape:
            debrid = {}
            
            if g.real_debrid_enabled() and g.get_setting('rd.cloudInspection') == 'true':
                debrid['real_debrid'] = True

            if g.premiumize_enabled() and g.get_setting('premiumize.cloudInspection') == 'true':
                debrid['premiumize'] = True

            self.usercloudSources = debrid_cloudfiles.sources().get_sources(debrid, query, episode)
            self.cloud_files += self.usercloudSources

        self.remainingProviders.remove('Cloud Inspection')

    def resolutionList(self):
        resolutions = []
        max_res = int(g.get_setting('general.maxResolution'))
        if max_res == 3 or max_res < 3:
            resolutions.append('NA')
        if max_res < 3:
            resolutions.append('720p')
        if max_res < 2:
            resolutions.append('1080p')
        if max_res < 1:
            resolutions.append('4K')

        return resolutions

    def debrid_priority(self):
        p = []

        if g.get_setting('premiumize.enabled') == 'true':
            p.append({'slug': 'premiumize', 'priority': int(g.get_setting('premiumize.priority'))})
        if g.get_setting('realdebrid.enabled') == 'true':
            p.append({'slug': 'real_debrid', 'priority': int(g.get_setting('rd.priority'))})
        if g.get_setting('alldebrid.enabled') == 'true':
            p.append({'slug': 'all_debrid', 'priority': int(g.get_setting('alldebrid.priority'))})

        p.append({'slug': '', 'priority': 11})

        p = sorted(p, key=lambda i: i['priority'])

        return p

    def sortSources(self, torrent_list, embed_list, filter_lang):
        sort_method = int(g.get_setting('general.sortsources'))

        sortedList = []

        resolutions = self.resolutionList()

        resolutions.reverse()

        for i in self.cloud_files:
            sortedList.append(i)

        if filter_lang:
            filter_lang = int(filter_lang)
            _torrent_list = torrent_list

            torrent_list = [i for i in _torrent_list if i['lang'] != filter_lang]

            embed_list = [i for i in embed_list if i['lang'] != filter_lang]

        elif g.get_setting('general.dubsort') == 'true':
            _torrent_list = torrent_list
            torrent_list = [i for i in _torrent_list if i['lang'] > 0] + \
                           [i for i in embed_list if i['lang'] > 0]

            embed_list = [i for i in _torrent_list if i['lang'] == 0] + \
                         [i for i in embed_list if i['lang'] == 0]

        debrid_priorities = self.debrid_priority()

        for resolution in resolutions:
            if sort_method == 0 or sort_method == 2:
                for debrid in debrid_priorities:
                    for torrent in torrent_list:
                        if debrid['slug'] == torrent['debrid_provider']:
                            if torrent['quality'] == resolution:
                                sortedList.append(torrent)

            if sort_method == 1 or sort_method == 2:
                for file in embed_list:
                    if file['quality'] == resolution:
                        sortedList.append(file)

        if sort_method == 1:
            for resolution in resolutions:
                for debrid in debrid_priorities:
                    for torrent in torrent_list:
                        if torrent['debrid_provider'] == debrid['slug']:
                            if torrent['quality'] == resolution:
                                sortedList.append(torrent)

        if sort_method == 0:
            for resolution in resolutions:
                for file in embed_list:
                    if file['quality'] == resolution:
                        sortedList.append(file)

        if g.get_setting('general.disable265') == 'true':
            sortedList = [i for i in sortedList if 'HEVC' not in i['info']]

        if g.get_setting('general.hidedub') == 'true':
            sortedList = [i for i in sortedList if i['lang'] != 2]

        return sortedList

    def colorNumber(self, number):

        if int(number) > 0:
            return g.color_string(number, 'green')
        else:
            return g.color_string(number, 'red')

    def updateProgress(self):

        list1 = [
                len([i for i in self.nyaaSources if i['quality'] == '4K']),
                len([i for i in self.nyaaSources if i['quality'] == '1080p']),
                len([i for i in self.nyaaSources if i['quality'] == '720p']),
                len([i for i in self.nyaaSources if i['quality'] == 'NA']),
            ]

        self.torrents_qual_len = list1

        list2 = [
                len([i for i in self.embedSources if i['quality'] == '4K']),
                len([i for i in self.embedSources if i['quality'] == '1080p']),
                len([i for i in self.embedSources if i['quality'] == '720p']),
                len([i for i in self.embedSources if i['quality'] == 'NA']),
            ]

        self.hosters_qual_len = list2

        return
