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

import os
import pickle
import random
import time
import urllib

try:
    import xbmc, xbmcgui
except:
    pass

from platformcode import config, logger
LIBTORRENT_PATH = config.get_setting("libtorrent_path", server="torrent", default='')

from servers import torrent as torr
lt, e, e1, e2 = torr.import_libtorrent(LIBTORRENT_PATH)

from cache import Cache
from dispatcher import Dispatcher
from file import File
from handler import Handler
from monitor import Monitor
from resume_data import ResumeData
from server import Server

try:
    BUFFER = int(config.get_setting("bt_buffer", server="torrent", default="50"))
except:
    BUFFER = 50
    config.set_setting("bt_buffer", "50", server="torrent")
DOWNLOAD_PATH = config.get_setting("bt_download_path", server="torrent", default=config.get_setting("downloadpath"))
BACKGROUND = config.get_setting("mct_background_download", server="torrent", default=True)
RAR = config.get_setting("mct_rar_unpack", server="torrent", default=True)
msg_header = 'Alfa BT Cliente Torrent'


class Client(object):
    INITIAL_TRACKERS = ['udp://tracker.openbittorrent.com:80',
                        'udp://tracker.istole.it:80',
                        'udp://open.demonii.com:80',
                        'udp://tracker.coppersurfer.tk:80',
                        'udp://tracker.leechers-paradise.org:6969',
                        'udp://exodus.desync.com:6969',
                        'udp://tracker.publicbt.com:80',
                        'http://tracker.torrentbay.to:6969/announce',
                        'http://tracker.pow7.com/announce',
                        'udp://tracker.ccc.de:80/announce',
                        'udp://open.demonii.com:1337',
                        'http://9.rarbg.com:2710/announce',
                        'http://bt.careland.com.cn:6969/announce',
                        'http://explodie.org:6969/announce',
                        'http://mgtracker.org:2710/announce',
                        'http://tracker.best-torrents.net:6969/announce',
                        'http://tracker.tfile.me/announce',
                        'http://tracker1.wasabii.com.tw:6969/announce',
                        'udp://9.rarbg.com:2710/announce',
                        'udp://9.rarbg.me:2710/announce',
                        'udp://coppersurfer.tk:6969/announce',
                        'http://www.spanishtracker.com:2710/announce',
                        'http://www.todotorrents.com:2710/announce'
                       ]                                                        ### Added some trackers from MCT

    VIDEO_EXTS = {'.avi': 'video/x-msvideo', '.mp4': 'video/mp4', '.mkv': 'video/x-matroska',
                  '.m4v': 'video/mp4', '.mov': 'video/quicktime', '.mpg': 'video/mpeg', '.ogv': 'video/ogg',
                  '.ogg': 'video/ogg', '.webm': 'video/webm', '.ts': 'video/mp2t', '.3gp': 'video/3gpp', 
                  '.rar': 'video/unrar'}

    def __init__(self, url=None, port=None, ip=None, auto_shutdown=True, wait_time=20, timeout=5, auto_delete=True,
                 temp_path=None, is_playing_fnc=None, print_status=False):

        # server
        if port:
            self.port = port
        else:
            self.port = random.randint(8000, 8099)
        if ip:
            self.ip = ip
        else:
            self.ip = "127.0.0.1"
        self.server = Server((self.ip, self.port), Handler, client=self)

        # Options
        if temp_path:
            self.temp_path = temp_path
        else:
            self.temp_path = DOWNLOAD_PATH
        self.is_playing_fnc = is_playing_fnc
        self.timeout = timeout
        self.auto_delete = auto_delete
        self.wait_time = wait_time
        self.auto_shutdown = auto_shutdown
        self.buffer_size = BUFFER
        self.first_pieces_priorize = BUFFER
        self.last_pieces_priorize = 5
        self.state_file = "state"
        try:
            self.torrent_paramss = {'save_path': self.temp_path, 'storage_mode': lt.storage_mode_t.storage_mode_allocate}
        except Exception, e:
            try:
                do = xbmcgui.Dialog()
                e = e1 or e2
                do.ok('ERROR en el cliente BT Libtorrent', 'Módulo no encontrado o imcompatible con el dispositivo.', 
                            'Reporte el fallo adjuntando un "log".', str(e))
            except:
                pass
            return

        # State
        self.has_meta = False
        self.meta = None
        self.start_time = None
        self.last_connect = 0
        self.connected = False
        self.closed = False
        self.file = None
        self.files = None
        self._th = None
        self.seleccion = 0
        self.index = 0

        # Sesion
        self._cache = Cache(self.temp_path)
        self._ses = lt.session()
        #self._ses.listen_on(0, 0)                                              ### ALFA: it blocks repro of some .torrents
        # Cargamos el archivo de estado (si existe)
        """                                                                     ### ALFA: it blocks repro of some .torrents
        if os.path.exists(os.path.join(self.temp_path, self.state_file)):
            try:
                f = open(os.path.join(self.temp_path, self.state_file), "rb")
                state = pickle.load(f)
                self._ses.load_state(state)
                f.close()
            except:
                pass
        """

        self._start_services()

        # Monitor & Dispatcher
        self._monitor = Monitor(self)
        if print_status:
            self._monitor.add_listener(self.print_status)
        self._monitor.add_listener(self._check_meta)
        self._monitor.add_listener(self.save_state)
        self._monitor.add_listener(self.priorize_start_file)
        self._monitor.add_listener(self.announce_torrent)

        if self.auto_shutdown:
            self._monitor.add_listener(self._auto_shutdown)

        self._dispatcher = Dispatcher(self)
        self._dispatcher.add_listener(self._update_ready_pieces)

        # Iniciamos la URL
        if url:
            self.start_url(url)

    def set_speed_limits(self, download=0, upload=0):
        """
        Función encargada de poner límites a la velocidad de descarga o subida
        """
        if isinstance(download, int) and download > 0:
            self._th.set_download_limit(download * 1024)
        if isinstance(upload, int) and download > 0:
            self._th.set_upload_limit(upload * 1024)
    
    def get_play_list(self):
        """
        Función encargada de generar el playlist
        """
        # Esperamos a lo metadatos
        while not self.has_meta:
            time.sleep(1)

        # Comprobamos que haya archivos de video
        if self.files:
            if len(self.files) > 1:
                return "http://" + self.ip + ":" + str(self.port) + "/playlist.pls"
            else:
                return "http://" + self.ip + ":" + str(self.port) + "/" + urllib.quote(self.files[0].path)

    def get_files(self):
        """
        Función encargada de genera el listado de archivos
        """
        # Esperamos a lo metadatos
        while not self.has_meta:
            time.sleep(1)
        files = []

        # Comprobamos que haya archivos de video
        if self.files:
            # Creamos el dict con los archivos
            for file in self.files:
                n = file.path
                u = "http://" + self.ip + ":" + str(self.port) + "/" + urllib.quote(n)
                s = fi
le.size
                files.append({"name": n, "url": u, "size": s})

        return files

    def _find_files(self, files, search=None):
        """
        Función encargada de buscar los archivos re
producibles del torrent
        """
        self.total_size = 0
        # Obtenemos los archivos que la extension este en la lista
        videos = filter(lambda f: self.VIDEO_EXTS.has_key(os