# -*- coding: utf-8 -*-

import sys
import bs4
import json

try :
    from utils import convb, htmlget
    from i18nlib import _
except:
    from .utils import convb, htmlget
    from .i18nlib import _

from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed

def do_req_get(url, ret, keys=None):
    """
    Do a request get and handle exceptions

    Args:
        url:
        ret:
        keys:

    Return:
        Return is text or json
    """

    if ret == "text":
        retval = ''
    elif ret == "json":
        retval = {}

    try:
        html = htmlget(url, params=keys)
        if ret == "text":
            retval = html
        elif ret == "json":
            retval = json.loads(html)
    except Exception as e:
        logging.info(e)
    finally:
        return retval


class TorrentSearch:

    def __init__(self, searchengine):
        self.searchengine = searchengine

    def __enter__(self):
        return self

    def __exit__(self, exception_type, exception_value, traceback):
        pass

    def search(self, sch, page=0):
        try : 
            #if self.searchengine == 'btdigg':
            #    s = [res for res in self._btdigg(sch, page)]
            #elif self.searchengine == 'torrentproject':
            #    s = [res for res in self._torrentproject(sch)]
            if self.searchengine == 'piratebay':
                s = [res for res in self._piratebay(sch)]
            elif self.searchengine == 'kickasstorrents':
                s = [res for res in self._kickasstorrents(sch)]
            elif self.searchengine == 'isohunt':
                s = [res for res in self._isohunt(sch)]
            elif self.searchengine == 'torrent9':
                s = [res for res in self._torrent9(sch)]
            elif self.searchengine == 'alphareign':
                s = [res for res in self._alphareign(sch, page)]
            elif self.searchengine == 'btdb':
                s = [res for res in self._btdb(sch, page)]
            elif self.searchengine == 'digbt':
                s = [res for res in self._digbt(sch, page)]
            elif self.searchengine == 'p2psearch':
                s = [res for res in self._p2psearch(sch, page)]
            elif self.searchengine == '*':
                s = self._search_all(sch)
            else:
                s = [res for res in self._alphareign(sch, 0)]
        except Exception as e:
            print(e)
            s = []
        return s

    def _search_all(self, sch):
        s = []
        searchengine_list = [self._piratebay, self._kickasstorrents, self._isohunt, self._torrent9, self._alphareign, self._btdb, self._digbt, self._p2psearch]
        with ThreadPoolExecutor(max_workers=5) as e:
            for searchengine in searchengine_list:
                try : 
                    e.map(s.append, searchengine(sch))
                except Exception as e:
                    print(e)
        return s

    def _btdigg(self, sch, page=0):
        """
        Return:
        List of dictionnaries with keys :
            name : torrent name
            magnet : magnet link
            size : size
            seed : number of seeds
        """

        url = 'https://btdigg.org/search'
        keys = {'q': sch, 'p': page}
        s = do_req_get(url, "text", keys)
        soup = bs4.BeautifulSoup(s, "html.parser")

        name = str()
        for i in soup.find_all('table', 'torrent_name_tbl'):
            for j in i.find_all('td', 'torrent_name'):
                name = j.a.string

            infos = i.find_all('span', 'attr_val')
            if not infos:
                continue
            else:
                size = infos[0].string
                # -- FIXME -- #
                # I hink this site doesn't give the seeds and leech
                # thats the last info btdigg had about this torrent
                seeds = infos[2].string
                leechs = infos[2].string

            magnet = str()
            for j in i.find_all('td', 'ttth'):
                magnet = j.a['href']

            d = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
            yield(d)


    def _torrentproject(self, sch):
        """
        Search on torrentproject.se

        Args:
            sch:

        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """
        url = 'https://torrentproject.se/'

        keys = {'s': sch, 'out': 'json'}
        json = do_req_get(url, "json", keys)
        for i in json:
            if i == 'total_found':
                continue
            else:
                th = json[i]['torrent_hash']
                magnet = 'magnet:?xt=urn:btih:{}'.format(th)
                # tj = do_req_get('{}/{}/trackers_json'.format(url, th), 'json')
                # for t in tj:
                #    magnet += '&tr={}'.format(t)

                name = json[i]['title']
                size = convb(json[i]['torrent_size'])
                seeds = json[i]['seeds']
                leechs = json[i]['leechs']

                d = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
                yield(d)


    def _piratebay(self, sch, page=0):
        """
        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """
        url = 'https://thepiratebay.org/search/{}///0'.format(sch)
        s = do_req_get(url, "text")
        soup = bs4.BeautifulSoup(s, "html.parser")

        name = str()
        magnet = str()
        size = str()
        seeds = str()
        leechs = str()
        for i in soup.find_all('td'):
            if not name:
                name_result = i.find('div', class_='detName')
                if name_result:
                    name = name_result.a.string

            if not magnet:
                alinks = i.find_all('a')
                for magnet_result in alinks:
                    href = magnet_result['href']
                    if href.startswith('magnet:'):
                        magnet = href
                        #magnet = href.split('&tr=')[0]  # to remove trackers

            if not size:
                size_result = i.find('font', class_='detDesc')
                if size_result:
                    size = size_result.text.split(',')[1].replace('Size', '').strip()

            if i.string:
                if not seeds:
                    seeds = i.string
                elif not leechs:
                    leechs = i.string

            if name and magnet and size and seeds and leechs :

                d = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
                name = str()
                magnet = str()
                size = str()
                seeds = str()
                leechs = str()
                yield(d)

    def _kickasstorrents(self, sch, page=0):
        """
        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """
        url = 'https://katcr.to/usearch/{}/'.format(sch)
        s = do_req_get(url, "text")
        soup = bs4.BeautifulSoup(s, "html.parser")

        name = str()
        magnet = str()
        size = str()
        seeds = str()
        leechs = str()
        divs = soup.find_all('data-sc-params')

        divs = soup.find_all('data-sc-params')
        results = [item["data-sc-params"] for item in soup.find_all() if "data-sc-params" in item.attrs]
        magnets = []
        for d in results:
            d = eval(d)
            if 'magnet' in d.keys():
                magnets.append(d['magnet'])


        all_tr = soup.find_all('tr', class_="even") + soup.find_all('tr', class_="odd")
        for tr, magnet in zip(all_tr, magnets):
            td = tr.find_all("td")

            name_result = td[0].find('a', class_='cellMainLink')
            if name_result:
                for content in name_result.contents:
                    name += content.string

            size_result = td[1]
            if size_result:
                for content in size_result.contents:
                    if size:
                        size = "{} {}".format(size, content.string)
                    else:
                        size = content.string

            seeds_result = td[4]
            if seeds_result:
                seeds = seeds_result.string

            leechs_result = td[5]
            if leechs_result:
                leechs = leechs_result.string


            if name != "" and magnet != "" and size != "" and seeds != "" and leechs != "":

                d = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
                name = str()
                magnet = str()
                size = str()
                seeds = str()
                leechs = str()
                yield(d)

    def _isohunt(self,sch, page=0):
        """
        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """

        url = 'https://isohunt.to/torrents/?'
        keys = {'ihq': sch}
        s = do_req_get(url, "text", keys)
        soup = bs4.BeautifulSoup(s, "html.parser")

        row = soup.find_all("td", class_="title-row")
        seeds_results = soup.find_all("td", class_="sy")
        size_results = soup.find_all("td", class_="size-row")

        with ThreadPoolExecutor(max_workers=5) as executor:
            for res in executor.map(isohunt_parse_results, zip(row, seeds_results, size_results)):
                yield res


    def _torrent9(self, sch, page=0):
        """
        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """
        thesch = sch.replace(' ', '-')
        baseurl = 'http://www.torrent9.biz'
        url = '{}/search_torrent/{}.html'.format(baseurl,thesch)
        s = do_req_get(url, "text")
        soup = bs4.BeautifulSoup(s, "html.parser")

        tmplist = []
        name = str()
        magnet = str()
        size = str()
        seeds = str()
        leechs = str()

        toparse = soup.find('tbody') 
        for d in toparse.find_all('td'):
            if d.find('a'):
                magnet = d.find('a')['href']
                # le titre est dans des <span>...
                name = [ s.string for s in d.a.find_all('span') ]
                name = ' '.join(name)
            else:
                if not size:
                    size = d.text
                elif not seeds :
                    seeds = d.text
                elif not leechs :
                    leechs = d.text
                    

            if name and magnet and size and seeds and leechs :
                res = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
                tmplist.append(res)
                name = str()
                magnet = str()
                size = str()
                seeds = str()
                leechs = str()

        with ThreadPoolExecutor(max_workers=5) as executor:
            future_mgt = { executor.submit(do_req_get, "{}/{}".format(baseurl,res['magnet']), "text") : res for res in tmplist }

            for f in as_completed(future_mgt):
                item = future_mgt[f]
                ms = f.result()
                magnetsoup = bs4.BeautifulSoup(ms, "html.parser")
                for m in magnetsoup.find_all('a', class_='download'):
                    if m['href'].startswith('magnet'):
                        magnet = m['href']
                        break
                item['magnet'] = magnet
                yield item



    def _alphareign(self, sch, page=0):
        """
        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """
        page = int(page) + 1
        url = 'https://alphareign.se/?'
        keys = {'query': sch, 'page': page}
        s = do_req_get(url, "text", keys)
        soup = bs4.BeautifulSoup(s, "html.parser")

        name = str()
        magnet = str()
        size = str()
        seeds = str()
        leechs = str()
        res = {}

        results = soup.find('div', id='results')
        for r in soup.find_all("div", class_="result"):
            name = r['data-name']
            size = convb(int(r['data-size']))
            seeds = r['data-seeders']
            leechs = r['data-leechers']
            link = r.find('a', alt='download torrent')
            magnet = link['href']

            if name and magnet and size and seeds and leechs :
                res = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
                name = str()
                magnet = str()
                size = str()
                seeds = str()
                leechs = str()

                yield res

    def _btdb(self, sch, page=0):
        """
        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """
        page = int(page) + 1
        baseurl = 'https://btdb.in'
        url = '{}/q/{}/{}'.format(baseurl, sch, page)
        s = do_req_get(url, "text")
        soup = bs4.BeautifulSoup(s, "html.parser")

        name = str()
        magnet = str()
        size = str()
        seeds = "?" 
        leechs = "?"
        res = {}

        for i in soup.find_all('h2', class_='item-title'):
            name = i.a['title']

            for r in soup.find_all('div', class_='item-meta-info'):
                size = r.find('span', class_='item-meta-info-value').string
                magnet = r.find('a', class_='magnet')['href']

                """
                size = r['data-size']
                seeds = r['data-seeders']
                leechs = r['data-leechers']
                """

                if name and magnet and size :
                    res = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
                    name = str()
                    magnet = str()
                    size = str()

                    yield res


    def _digbt(self, sch, page=0):
        """
        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """
        page = int(page) + 1
        baseurl = 'https://www.digbt.org'
        url = '{}/search/{}-time-{}'.format(baseurl, sch, page)
        s = do_req_get(url, "text")
        soup = bs4.BeautifulSoup(s, "html.parser")

        name = str()
        magnet = str()
        size = str()
        seeds = '?'
        leechs = '?'
        res = {}

        for r in soup.find_all('td', class_='x-item'):
            for a in r.find_all('a', class_='title'):
                if a['href'].startswith('magnet:?'):
                    magnet = a['href']
                else:
                    name = a.string

            d = r.find('div', class_='tail').text
            d = d.strip().split(' ') # ugly, FIXME
            size = d[3]

            if name and magnet and size :
                res = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
                name = str()
                magnet = str()
                size = str()

                yield res

    def _p2psearch(self, sch, page=0):
        """
        Return:
            List of dictionnaries with keys :
                name : torrent name
                magnet : magnet link
                size : size
                seed : number of seeds
        """
        page = int(page) + 1
        if page < 10:
            page = page * 10
        baseurl = 'https://www.p2psearch.net'
        url = '{}/search/{}/list{}'.format(baseurl, sch, page)
        s = do_req_get(url, "text")
        soup = bs4.BeautifulSoup(s, "html.parser")

        name = str()
        magnet = str()
        size = str()
        seeds = '?'
        leechs = '?'
        tmplist = []
        res = {}

        for li in soup.find_all('li'):
            title = li.find('p', class_="title")
            param = li.find('p', class_="param")
            if title : 
                name = title.a['title']
                magnet = title.a['href']

            if param:
                size = param.text.splitlines()[3]
                size = size.strip().split(':')[1]
                
            if name and magnet and size :
                res = {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}
                tmplist.append(res)
                name = str()
                magnet = str()
                size = str()
                
        with ThreadPoolExecutor(max_workers=5) as executor:
            future_mgt = { executor.submit(do_req_get, "{}{}".format(baseurl,res['magnet']), "text") : res for res in tmplist }

            for f in as_completed(future_mgt):
                item = future_mgt[f]
                ms = f.result()
                mgtsoup = bs4.BeautifulSoup(ms, "html.parser")
                magnet = mgtsoup.find('textarea', class_="magnet-link").text

                item['magnet'] = magnet
                yield item



def isohunt_parse_results(z):
    """
    parse isohunt results 
    return a dic of torrent description
    """
    td, s, sz = z

    name = str()
    magnet = str()
    size = str()
    seeds = str()
    leechs = str()

    a = td.find('a')
    torlink = "https://isohunt.to{}".format(a['href'])
    name = a.text
    seeds = s.text
    size = sz.text

    s = do_req_get(torlink, "text")
    soup = bs4.BeautifulSoup(s, "html.parser")
    magnet = soup.find("a", class_="btn-magnet")['href']

    return {'name': name, 'magnet': magnet, 'size': size, 'seeds': seeds, "leechs": leechs}


    
if __name__ == '__main__':
    with TorrentSearch('p2psearch') as ts:
        s = ts.search('vikings vostfr', 0)
        print(s)




# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
