/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80*/
/*global window, RSVP, rJS, document, tv4, WebTorrent*/
(function (window, document, rJS, RSVP, tv4, WebTorrent) {

  function createWebTorrent(rtcconfig) {
    return new WebTorrent({
      tracker: {
        rtcConfig: rtcconfig
      }
    });
  }

  function checkDownloadTorrent(gadget, index_dict) {
      var client,
          counter = 0,
          downloading,
          magnet;
      if (!index_dict.infohash || ! index_dict.namehash)
        return;
      return gadget.state.model_gadget.getRtcconfig()
        .push(function (rtcconfig) {
          magnet = "magnet:?xt=urn:btih:";
          // XXX - hardcoded tracker uri
          magnet += index_dict.infohash + "&dn=" + index_dict.namehash +
            "&tr=wss://tracker.openwebtorrent.com&tr=" +
            "wss://softinst140244.host.vifib.net";
          client = createWebTorrent(rtcconfig);
          // XXX - find a better way to check if torrent is downloadable
          return client.add(magnet, function (torrent) {
            torrent.on('error', function (err) {
              console.error(err);
            });
          });
        })
        .push(function (torrent) {
          function checkReady() {
            if (torrent.ready)
              return true;
            if (counter >= 7)
              return false;
            return RSVP.delay(1000)
            .then(function () {
              counter += 1;
              return checkReady();
            });
          }

          return new RSVP.Queue()
          .push(function () {
            return checkReady();
          })
          .push(function (status) {
            // cancel torrent
            torrent.destroy(function (err) {
              console.error(err);
            });
            if (status)
              // torrent will download...
              return gadget.redirect({command: 'change', options: {
                page : "mynij_torrent",
                magnet_uri: magnet
              }});
          });
        });
    }

  rJS(window)

  .declareAcquiredMethod("redirect", "redirect")
  .declareAcquiredMethod("getUrlParameter", "getUrlParameter")
  .declareAcquiredMethod("getSetting", "getSetting")
  .declareAcquiredMethod("setSetting", "setSetting")
  .declareAcquiredMethod("notifySubmitted", "notifySubmitted")
  .declareAcquiredMethod("updateHeader", "updateHeader")

  .ready(function () {
    var gadget = this;
    return this.getDeclaredGadget("model")
      .push(function (model) {
        return gadget.changeState({
          model_gadget: model
        });
      });
  })

  .onStateChange(function () {
    var gadget = this,
        doc,
        promise_list = [],
        schema,
        i;

    if (!gadget.state.source_url)
      return;
    return gadget.state.model_gadget.getSourceSchema()
      .push(function (s) {
        schema = s;
        return gadget.loadSource(gadget.state.source_url);
      })
      .push(function (source_string) {
        var source_list,
            valid = false,
            a_json = true,
            message = "Failed to download source file from specified url";
        try {
          source_list = JSON.parse(source_string);
          valid = tv4.validate(source_list, schema);
        } catch (e) {
          console.error(e);
          a_json = false;
        }
        if (!source_string || !a_json || !valid) {
          if (!a_json || !valid) {
            message = "Downloaded file is not a valid JSON source!";
          }
          return gadget.notifySubmitted({
            message: message,
            status: "error"
          })
          .push(function () {
            return gadget.redirect({command: 'display', options: {
              page : "mynij_search"
            }});
          });
        }
        for (i = 0; i < source_list.length; i += 1) {
          doc  = {};
          doc.title = source_list[i].title;
          doc.links = source_list[i].links;
          doc.status = "not built";
          doc.description = source_list[i].description || "";
          doc.logo = source_list[i].logo || "";
          promise_list.push(gadget.state.model_gadget.createIndexDoc(doc));
        }
        return new RSVP.Queue()
          .push(function () {
            return RSVP.all(promise_list);
          })
          .push(function (result) {
            var count = result.length;

            return new RSVP.Queue()
            .push(function () {
              return checkDownloadTorrent(gadget, source_list[0]);
            })
            .push(function () {
              return gadget.getSetting("build_dict", {});
            })
            .push(function (build_dict) {
              var i;

              for (i = 0; i < result.length; i += 1) {
                build_dict[result[i]] = {
                  links: source_list[i].links,
                  index_name: source_list[i].title,
                  jio_key: result[i],
                  id: Date.now(),
                  infohash: source_list[i].infohash,
                  namehash: source_list[i].namehash
                };
              }
              return gadget.setSetting("build_dict", build_dict);
            })
            .push(function () {
              var options = {page : "mynij_search",
                             msg: count + " Source(s) correctly imported!\n" +
                             "Imported source(s) will now build!"};
              return gadget.redirect({command: 'display', options: options});
            });
          });
      });
  })

  .declareMethod("loadSource", function (url) {
    return new RSVP.Queue()
    .push(function () {
      return jIO.util.ajax({
        url : url
      });
    })
    .push(undefined, function (error) {
      console.log(error);
      return undefined;
    })
    .push(function (response) {
      if (!response)
        return undefined;
      return response.target.responseText;
    });
  })

  .declareMethod("render", function (options) {
    var gadget = this;
    return gadget.updateHeader({page_title: "JSON Source import"})
      .push(function () {
        return gadget.changeState({
          source_url: options.url
        });
      });
  });

}(window, document, rJS, RSVP, tv4, WebTorrent));