'use strict'
var Path = require('path')
var WebTorrent = require('webtorrent')

var Log = require(Path.join(__base, 'src/worker/log.js'))

/**
 * Torrent Client.
 * @constructor
 */
function Client () {
  this.client = new WebTorrent()
  this.torrentLink = ''
  this.torrent = {}
  this.timeout = new Date().getTime()

  this.startFunction = function () {}
  this.updateFunction = function () {}
  this.doneFunction = function () {}
}

/**
 * Download a torrent.
 * @param {string} torrentLink - The link or magnet of the torrent.
*/
Client.prototype.download = function (torrentLink) {
  var self = this

  self.torrentLink = torrentLink
  Log.echo('Start: ' + torrentLink)

  var timeout = setTimeout(function () {
    self.client.destroy(function () {
      self.doneFunction(true, null, null)
    })
  }, __config.client.timeout)
  // download the torrent
  self.client.add(torrentLink, {
    path: __config.torrent.downloads
  }, function (torrent) {
    clearTimeout(timeout)
    // On torrent start
    self.torrent = torrent
    Log.print('Start torrent: ' + self.torrent.name)
    // emit start function with infoHash
    self.startFunction(torrent.infoHash)

    self.torrent.on('download', function (chunkSize) {
      var currentTime = new Date().getTime()
      if ((currentTime - self.timeout) > __config.client.updateTimeout) {
        // emit update function with torrent infos
        self.updateFunction(self.getTorrent())
        self.timeout = currentTime
      }
    })

    self.torrent.on('done', function () {
      Log.print('Finish torrent: ' + self.torrent.name)
      // emit done function with torrent hash and name
      self.doneFunction(false, self.torrent.infoHash, self.torrent.name)
    })

    self.torrent.on('noPeers', function () {
      Log.print('No peers: ' + self.torrent.name)
      // emit done function with torrent hash and name
      self.doneFunction(false, self.torrent.infoHash, self.torrent.name)
    })

    self.torrent.on('error', function (err) {
      Log.print('Error: ' + err)
    })
  })
}

/**
 * Stop the current torrent of the client.
*/
Client.prototype.stop = function () {
  var self = this
  if (self.torrent) {
    self.torrent.pause()
    setTimeout(function () {
      self.torrent.destroy()
    }, 1000)
  }
}

/**
 * Get information about the current torrent of the client.
 * @return {object} - Torrent informations.
*/
Client.prototype.getTorrent = function () {
  var t = {}
  if (this.torrent) {
    if (!this.torrent.client.destroyed) {
      t.name = this.torrent.name
      t.size = this.torrent.length
      t.hash = this.torrent.infoHash
      t.sdown = this.torrent.downloadSpeed
      t.sup = this.torrent.uploadSpeed
      t.down = this.torrent.downloaded
      t.up = this.torrent.uploaded
      t.seed = this.torrent._peersLength
      t.progress = this.torrent.progress
      t.timeRemaining = this.torrent.timeRemaining
    }
  }

  return t
}

/**
 * Set function for the client events.
 * @param {string} what - Name of the event (start, download, done).
 * @param {function} f - Function to execute.
*/
Client.prototype.on = function (what, f) {
  switch (what) {
    case 'start':
      this.startFunction = f
      break
    case 'download':
      // function(download){}
      this.updateFunction = f
      break
    case 'done':
      // function(torrentHash, torrentName){}
      this.doneFunction = f
      break
  }
}

module.exports = Client

@@ -1052,37 +1052,32 @@
 rt torrent: ' + 
-self.
 torrent.name)%0A  
@@ -1157,29 +1157,24 @@
 oHash)%0A%0A    
-self.
 torrent.on('
@@ -1471,37 +1471,32 @@
   %7D%0A    %7D)%0A%0A    
-self.
 torrent.on('done
@@ -1646,37 +1646,32 @@
 Function(false, 
-self.
 torrent.infoHash
@@ -1664,37 +1664,32 @@
 rrent.infoHash, 
-self.
 torrent.name)%0A  
@@ -1690,37 +1690,32 @@
 me)%0A    %7D)%0A%0A    
-self.
 torrent.on('noPe
@@ -1761,29 +1761,24 @@
  peers: ' + 
-self.
 torrent.name
@@ -1865,21 +1865,16 @@
 (false, 
-self.
 torrent.
@@ -1883,21 +1883,16 @@
 foHash, 
-self.
 torrent.
@@ -1905,29 +1905,24 @@
     %7D)%0A%0A    
-self.
 torrent.on('

improve visual