# -*- coding: utf-8 -*-
# @author: jeix

import socket
import struct

from os import remove
from os.path import exists
from select import select
from time import time

from pyload.plugin.Plugin import Abort


class XDCCRequest(object):

    def __init__(self, timeout=30, proxies={}):

        self.proxies = proxies
        self.timeout = timeout

        self.filesize = 0
        self.recv = 0
        self.speed = 0

        self.abort = False


    def createSocket(self):
        # proxytype = None
        # proxy = None
        # if self.proxies.has_key("socks5"):
            # proxytype = socks.PROXY_TYPE_SOCKS5
            # proxy = self.proxies['socks5']
        # elif self.proxies.has_key("socks4"):
            # proxytype = socks.PROXY_TYPE_SOCKS4
            # proxy = self.proxies['socks4']
        # if proxytype:
            # sock = socks.socksocket()
            # t = _parse_proxy(proxy)
            # sock.setproxy(proxytype, addr=t[3].split(":")[0], port=int(t[3].split(":")[1]), username=t[1], password=t[2])
        # else:
            # sock = socket.socket()
        # return sock

        return socket.socket()


    def download(self, ip, port, filename, irc, progress=None):

        ircbuffer = ""
        lastUpdate = time()
        cumRecvLen = 0

        dccsock = self.createSocket()

        dccsock.settimeout(self.timeout)
        dccsock.connect((ip, port))

        if exists(filename):
            i = 0
            nameParts = filename.rpartition(".")
            while True:
                newfilename = "%s-%d%s%s" % (nameParts[0], i, nameParts[1], nameParts[2])
                i += 1

                if not exists(newfilename):
                    filename = newfilename
                    break

        fh = open(filename, "wb")

        # recv loop for dcc socket
        while True:
            if self.abort:
                dccsock.close()
                fh.close()
                remove(filename)
                raise Abort

            self._keepAlive(irc, ircbuffer)

            data = dccsock.recv(4096)
            dataLen = len(data)
            self.recv += dataLen

            cumRecvLen += dataLen

            now = time()
            timespan = now - lastUpdate
            if timespan > 1:
                self.speed = cumRecvLen / timespan
                cumRecvLen = 0
                lastUpdate = now

                if progress:
                    progress(self.percent)

            if not data:
                break

            fh.write(data)

            # acknowledge data by sending number of recceived bytes
            dccsock.send(struct.pack('!I', self.recv))

        dccsock.close()
        fh.close()

        return filename


    def _keepAlive(self, sock, *readbuffer):
        fdset = select([sock], [], [], 0)
        if sock not in fdset[0]:
            return

        readbuffer += sock.recv(1024)
        temp = readbuffer.split("\n")
        readbuffer = temp.pop()

        for line in temp:
            line  = line.rstrip()
            first = line.split()
            if first[0] == "PING":
                sock.send("PONG %s\r\n" % first[1])


    def abortDownloads(self):
        self.abort = True


    @property
    def size(self):
        return self.filesize


    @property
    def arrived(self):
        return self.recv


    @property
    def percent(self):
        return (self.recv * 100) / self.filesize if elf.filesize else 0


    def close(self):
        pass