// Generated by IcedCoffeeScript 1.7.1-f
(function() {
  var ProgressBar, Request, format_url, http, https, iced, parse, request, request_mikeal, request_progress, single, urlmod, __iced_k, __iced_k_noop;

  iced = require('iced-runtime');
  __iced_k = __iced_k_noop = function() {};

  https = require('https');

  http = require('http');

  parse = require('url').parse;

  ProgressBar = require('progress');

  urlmod = require('url');

  request = require('request');

  Request = (function() {
    function Request(_arg) {
      var progress, uri, url;
      url = _arg.url, uri = _arg.uri, this.headers = _arg.headers, progress = _arg.progress;
      url = url || uri;
      this._res = null;
      this._data = [];
      this._err = null;
      this.uri = this.url = typeof url === 'string' ? parse(url) : url;
      this._bar = null;
      this._opts = {
        progress: progress
      };
    }

    Request.prototype.run = function(cb) {
      this._done_cb = cb;
      return this._launch();
    };

    Request.prototype._make_opts = function() {
      var opts;
      opts = {
        host: this.url.hostname,
        port: this.url.port || (this.url.protocol === 'https:' ? 443 : 80),
        path: this.url.path,
        method: 'GET',
        headers: this.headers
      };
      if (this.url.protocol === 'https:') {
        opts.mod = https;
        opts.agent = new https.Agent(opts);
      } else {
        opts.mod = http;
      }
      return opts;
    };

    Request.prototype._launch = function() {
      var opts, req;
      opts = this._make_opts();
      req = opts.mod.request(opts, (function(_this) {
        return function(res) {
          var l, _ref;
          if ((_this._opts.progress != null) && ((l = (_ref = res.headers) != null ? _ref["content-length"] : void 0) != null) && !(isNaN(l = parseInt(l, 10))) && l > _this._opts.progress) {
            _this._bar = new ProgressBar("Download " + _this.url.path + " [:bar] :percent :etas (" + l + " bytes total)", {
              complete: "=",
              incomplete: ' ',
              width: 50,
              total: l
            });
          }
          _this._res = res;
          res.request = _this;
          res.on('data', function(d) {
            var _ref1;
            _this._data.push(d);
            return (_ref1 = _this._bar) != null ? _ref1.tick(d.length) : void 0;
          });
          return res.on('end', function() {
            return _this._finish();
          });
        };
      })(this));
      req.end();
      return req.on('error', (function(_this) {
        return function(e) {
          _this._err = e;
          return _this._finish();
        };
      })(this));
    };

    Request.prototype._finish = function() {
      var cb;
      cb = this._done_cb;
      this._done_cb = null;
      return cb(this._err, this._res, Buffer.concat(this._data));
    };

    return Request;

  })();

  single = function(opts, cb) {
    return (new Request(opts)).run(cb);
  };

  format_url = function(u) {
    if (typeof u === 'string') {
      return u;
    } else {
      return urlmod.format(u);
    }
  };

  request_progress = function(opts, cb) {
    var body, err, found, i, lim, prev_url, res, url, ___iced_passed_deferral, __iced_deferrals, __iced_k, _begin, _end, _positive;
    __iced_k = __iced_k_noop;
    ___iced_passed_deferral = iced.findDeferral(arguments);
    lim = opts.maxRedirects || 10;
    res = body = null;
    found = false;
    if (typeof opts.url === 'string') {
      opts.url = parse(opts.url);
    }
    (function(_this) {
      return (function(__iced_k) {
        var _i, _results, _while;
        i = 0;
        _begin = 0;
        _end = lim;
        _positive = _end > _begin;
        _results = [];
        _while = function(__iced_k) {
          var _break, _continue, _next;
          _break = function() {
            return __iced_k(_results);
          };
          _continue = function() {
            return iced.trampoline(function() {
              if (_positive) {
                i += 1;
              } else {
                i -= 1;
              }
              return _while(__iced_k);
            });
          };
          _next = function(__iced_next_arg) {
            _results.push(__iced_next_arg);
            return _continue();
          };
          if (!!((_positive === true && i >= lim) || (_positive === false && i <= lim))) {
            return _break();
          } else {

            prev_url = opts.url;
            (function(__iced_k) {
              __iced_deferrals = new iced.Deferrals(__iced_k, {
                parent: ___iced_passed_deferral,
                filename: "/home/max/src/keybase/node-installer/src/request.iced"
              });
              single(opts, __iced_deferrals.defer({
                assign_fn: (function() {
                  return function() {
                    err = arguments[0];
                    res = arguments[1];
                    return body = arguments[2];
                  };
                })(),
                lineno: 93
              }));
              __iced_deferrals._fulfill();
            })(function() {
              (function(__iced_k) {
                if (err != null) {
                  (function(__iced_k) {
_break()
                  })(__iced_k);
                } else {
                  (function(__iced_k) {
                    var _ref;
                    if (!((_ref = res.statusCode) === 301 || _ref === 302)) {
                      found = true;
                      (function(__iced_k) {
_break()
                      })(__iced_k);
                    } else {
                      (function(__iced_k) {
                        var _ref1;
                        if ((url = (_ref1 = res.headers) != null ? _ref1.location : void 0) == null) {
                          err = new Error("Can't find a location in header for redirect");
                          (function(__iced_k) {
_break()
                          })(__iced_k);
                        } else {
                          url = parse(url);
                          if (!url.host) {
                            url.host = prev_url.host;
                            url.hostname = prev_url.hostname;
                            url.port = prev_url.port;
                            url.protocol = prev_url.protocol;
                          }
                          return __iced_k(opts.url = url);
                        }
                      })(__iced_k);
                    }
                  })(__iced_k);
                }
              })(_next);
            });
          }
        };
        _while(__iced_k);
      });
    })(this)((function(_this) {
      return function() {
        err = err != null ? err : !found ? new Error("Too many redirects") : res.statusCode >= 200 && res.statusCode < 300 ? null : new Error("In " + (format_url(opts.url)) + ": HTTP failure, code " + res.statusCode);
        return cb(err, res, body);
      };
    })(this));
  };

  request_mikeal = function(opts, cb) {
    var body, err, res, rv, url, url_s, which, ___iced_passed_deferral, __iced_deferrals, __iced_k;
    __iced_k = __iced_k_noop;
    ___iced_passed_deferral = iced.findDeferral(arguments);
    opts.encoding = null;
    rv = new iced.Rendezvous();
    url = opts.url || opts.uri;
    url_s = typeof url === 'object' ? url.format() : url;
    request(opts, rv.id(true).defer({
      assign_fn: (function(_this) {
        return function() {
          return function() {
            err = arguments[0];
            res = arguments[1];
            return body = arguments[2];
          };
        };
      })(this)(),
      lineno: 124,
      context: __iced_deferrals
    }));
    process.stderr.write("Downloading...");
    (function(_this) {
      return (function(__iced_k) {
        var _results, _while;
        _results = [];
        _while = function(__iced_k) {
          var _break, _continue, _next;
          _break = function() {
            return __iced_k(_results);
          };
          _continue = function() {
            return iced.trampoline(function() {
              return _while(__iced_k);
            });
          };
          _next = function(__iced_next_arg) {
            _results.push(__iced_next_arg);
            return _continue();
          };
          if (!true) {
            return _break();
          } else {
            setTimeout(rv.id(false).defer({
              lineno: 128,
              context: __iced_deferrals
            }), 100);
            (function(__iced_k) {
              __iced_deferrals = new iced.Deferrals(__iced_k, {
                parent: ___iced_passed_deferral,
                filename: "/home/max/src/keybase/node-installer/src/request.iced"
              });
              rv.wait(__iced_deferrals.defer({
                assign_fn: (function() {
                  return function() {
                    return which = arguments[0];
                  };
                })(),
                lineno: 129
              }));
              __iced_deferrals._fulfill();
            })(function() {
              (function(__iced_k) {
                if (which) {
                  (function(__iced_k) {
_break()
                  })(__iced_k);
                } else {
                  return __iced_k();
                }
              })(function() {
                return _next(process.stderr.write("."));
              });
            });
          }
        };
        _while(__iced_k);
      });
    })(this)((function(_this) {
      return function() {
        process.stderr.write("..done\n");
        return cb(err, res, body);
      };
    })(this));
  };

  exports.request = function(opts, cb) {
    if (opts.proxy != null) {
      return request_mikeal(opts, cb);
    } else {
      return request_progress(opts, cb);
    }
  };

}).call(this);
