// Generated by IcedCoffeeScript 1.7.1-c
(function() {
  var Client, E, PackageJson, certs, dcopy, env, iced, k, log, m, proxyca, request, tor, urlmod, __iced_k, __iced_k_noop, _cli, _fn,
    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
    __slice = [].slice;

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

  request = require('request');

  env = require('./env').env;

  urlmod = require('url');

  E = require('./err').E;

  log = require('./log');

  certs = require('./ca').certs;

  PackageJson = require('./package').PackageJson;

  proxyca = require('./proxyca');

  tor = require('./tor');

  m = function(dict, method) {
    dict.method = method;
    return dict;
  };

  dcopy = function(d) {
    var k, out, v;
    out = {};
    for (k in d) {
      v = d[k];
      out[k] = v;
    }
    return out;
  };

  exports.Client = Client = (function() {
    function Client(headers) {
      this.headers = headers;
      this._cookies = {};
      this._session = null;
      this._csrf = null;
      this._warned = false;
    }

    Client.prototype.set_headers = function(h) {
      return this.headers = h;
    };

    Client.prototype.get_headers = function() {
      return this.headers;
    };

    Client.prototype.add_headers = function(d) {
      var k, v;
      this.headers || (this.headers = {});
      for (k in d) {
        v = d[k];
        this.headers[k] = v;
      }
      return true;
    };

    Client.prototype.set_session = function(s) {
      if (!tor.strict()) {
        this.add_headers({
          "X-Keybase-Session": s
        });
        return this._session = s;
      }
    };

    Client.prototype.clear_session = function() {
      this._session = null;
      if (this.headers != null) {
        return delete this.headers['X-Keybase-Session'];
      }
    };

    Client.prototype.clear_csrf = function() {
      this._csrf = null;
      if (this.headers != null) {
        return delete this.headers['X-CSRF-Token'];
      }
    };

    Client.prototype.set_csrf = function(c) {
      if (!tor.strict()) {
        this.add_headers({
          "X-CSRF-Token": c
        });
        return this._csrf = c;
      }
    };

    Client.prototype.get_session = function() {
      return this._session;
    };

    Client.prototype.get_csrf = function() {
      return this._csrf;
    };

    Client.prototype._find_cookies = function(res) {
      var cookie_line, name, parts, v, val, _i, _len, _ref, _ref1, _results;
      if ((v = (_ref = res.headers) != null ? _ref['set-cookie'] : void 0) != null) {
        _results = [];
        for (_i = 0, _len = v.length; _i < _len; _i++) {
          cookie_line = v[_i];
          parts = cookie_line.split("; ");
          if (parts.length) {
            _ref1 = parts[0].split("="), name = _ref1[0], val = _ref1[1];
            _results.push(this._cookies[name] = decodeURIComponent(val));
          } else {
            _results.push(void 0);
          }
        }
        return _results;
      }
    };

    Client.prototype.error_for_humans = function(_arg) {
      var err, host, port, uri, uri_fields;
      err = _arg.err, uri = _arg.uri, uri_fields = _arg.uri_fields;
      host = uri_fields.hostname;
      port = uri_fields.port;
      switch (err.code) {
        case 'ENOTFOUND':
          return new E.ReqNotFoundError("Host '" + host + "' wasn't found in DNS; check your network");
        case 'ECONNREFUSED':
          return new E.ReqConnRefusedError("Host '" + host + ":" + port + "' refused connection; maybe the server is down");
        default:
          return new E.ReqGenericError("Could not access URL: " + uri);
      }
    };

    Client.prototype.req = function(_arg, cb) {
      var args, body, ca, endpoint, err, http_status, jar, json, kb_status, method, need_cookie, opts, pathname, pcc, pjs, prx, res, search, tha, tls, tor_on, uri_fields, v, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      method = _arg.method, endpoint = _arg.endpoint, args = _arg.args, http_status = _arg.http_status, kb_status = _arg.kb_status, pathname = _arg.pathname, search = _arg.search, json = _arg.json, jar = _arg.jar, need_cookie = _arg.need_cookie;
      method || (method = 'GET');
      tha = null;
      if ((tor_on = tor.enabled())) {
        tha = tor.hidden_address();
        log.debug("| Using tor hidden address: " + (JSON.stringify(tha)));
      }
      if (!(jar != null) && !(tor.strict()) && (need_cookie || !tor_on)) {
        jar = true;
      }
      if (json == null) {
        json = true;
      }
      opts = {
        method: method,
        json: json
      };
      if (jar != null) {
        opts.jar = jar;
      }
      opts.headers = this.headers != null ? dcopy(this.headers) : {};
      pjs = new PackageJson;
      opts.headers["X-Keybase-Client"] = pjs.identify_as();
      opts.headers["User-Agent"] = pjs.user_agent();
      kb_status || (kb_status = ["OK"]);
      http_status || (http_status = [200]);
      tls = !tor_on && !(env().get_no_tls());
      uri_fields = {
        protocol: "http" + (tls ? 's' : ''),
        hostname: tor_on ? tha.hostname : env().get_host(),
        port: tor_on ? tha.port : env().get_port(),
        pathname: pathname || [env().get_api_uri_prefix(), endpoint + ".json"].join("/"),
        search: search
      };
      if (method === 'GET' || method === 'DELETE') {
        uri_fields.query = args;
      }
      opts.uri = urlmod.format(uri_fields);
      if (method === 'POST') {
        opts.body = args;
      }
      log.debug("+ request to " + endpoint + " (" + opts.uri + ") (cookie=" + (!!jar) + ")");
      if ((prx = env().get_proxy()) != null) {
        log.debug("| using proxy " + prx);
        opts.proxy = prx;
      }
      if (!tls) {

      } else if ((opts.proxy != null) && ((pcc = proxyca.get()) != null)) {
        log.debug("| Using proxy CA certs " + (pcc.files().join(':')));
        opts.ca = pcc.data().concat([ca]);
      } else if ((ca = certs[uri_fields.hostname]) != null) {
        log.debug("| Adding a custom CA for host " + uri_fields.hostname + " when tls=" + tls);
        opts.ca = [ca];
      }
      tor.agent(opts);
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/Users/max/src/keybase/node-client/src/req.iced",
            funcname: "Client.req"
          });
          request(opts, __iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                err = arguments[0];
                res = arguments[1];
                return body = arguments[2];
              };
            })(),
            lineno: 152
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          var _ref, _ref1, _ref2, _ref3, _ref4;
          if (typeof err !== "undefined" && err !== null) {
            err = _this.error_for_humans({
              err: err,
              uri: opts.uri,
              uri_fields: uri_fields
            });
          } else if (!(_ref = res.statusCode, __indexOf.call(http_status, _ref) >= 0)) {
            if (res.statusCode === 400 && ((_ref1 = res.headers) != null ? _ref1["x-keybase-client-unsupported"] : void 0)) {
              v = res.headers["x-keybase-client-upgrade-to"];
              err = new E.RequiredUpgradeError("Upgrade is required! Run `keybase-installer` to upgrade to v" + v);
              err.upgrade_to = v;
            } else {
              err = new E.HttpError("Got reply " + res.statusCode);
            }
          } else if (json && !(_ref2 = typeof body !== "undefined" && body !== null ? (_ref3 = body.status) != null ? _ref3.name : void 0 : void 0, __indexOf.call(kb_status, _ref2) >= 0)) {
            err = new E.KeybaseError("" + body.status.desc + " (error #" + body.status.code + ")");
            err.fields = ((_ref4 = body.status) != null ? _ref4.fields : void 0) || {};
            opts.agent = null;
            log.debug("Full request: " + (JSON.stringify(opts)));
            log.debug("Full reply: " + (JSON.stringify(body)));
          } else {
            if (((v = res.headers["x-keybase-client-upgrade-to"]) != null) && !_this._warned) {
              log.warn("Upgrade suggested! Run `keybase-installer` to upgrade to v" + v);
              _this._warned = true;
            }
            _this._find_cookies(res);
          }
          log.debug("- request to " + endpoint + " -> " + err);
          return cb(err, body, res);
        };
      })(this));
    };

    Client.prototype.post = function(args, cb) {
      return this.req(m(args, "POST"), cb);
    };

    Client.prototype.get = function(args, cb) {
      return this.req(m(args, "GET"), cb);
    };

    Client.prototype.cookies = function() {
      return this._cookies;
    };

    return Client;

  })();

  exports.client = _cli = new Client();

  _fn = function(fname) {
    return exports[fname] = function() {
      var args;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      return _cli[fname].apply(_cli, args);
    };
  };
  for (k in Client.prototype) {
    _fn(k);
  }

}).call(this);
