// Generated by IcedCoffeeScript 1.8.0-e
(function() {
  var Base, BitbucketBinding, CoinbaseBinding, DnsBinding, GenericWebSiteBinding, GithubBinding, HackerNewsBinding, KeybaseBinding, RedditBinding, SocialNetworkBinding, TwitterBinding, WebServiceBinding, cieq, constants, has_non_ascii, iced, urlmod, __iced_k, __iced_k_noop, _ref,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

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

  _ref = require('./base'), cieq = _ref.cieq, Base = _ref.Base;

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

  urlmod = require('url');

  WebServiceBinding = (function(_super) {
    __extends(WebServiceBinding, _super);

    function WebServiceBinding() {
      return WebServiceBinding.__super__.constructor.apply(this, arguments);
    }

    WebServiceBinding.prototype._v_customize_json = function(ret) {
      var o;
      if ((o = this.service_obj()) != null) {
        return ret.body.service = o;
      }
    };

    WebServiceBinding.prototype._service_obj_check = function(x) {
      return !(x != null);
    };

    WebServiceBinding.prototype._optional_sections = function() {
      return WebServiceBinding.__super__._optional_sections.call(this).concat(["revoke", "service"]);
    };

    WebServiceBinding.prototype.resource_id = function() {
      return "";
    };

    WebServiceBinding.prototype._type = function() {
      return constants.sig_types.web_service_binding;
    };

    WebServiceBinding.prototype._v_check = function(_arg, cb) {
      var err, json, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      json = _arg.json;
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/Users/sidney/src/keybase/proofs/src/web_service.iced",
            funcname: "WebServiceBinding._v_check"
          });
          WebServiceBinding.__super__._v_check.call(_this, {
            json: json
          }, __iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                return err = arguments[0];
              };
            })(),
            lineno: 38
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          var _ref1;
          if (!(typeof err !== "undefined" && err !== null) && !(_this._service_obj_check(json != null ? (_ref1 = json.body) != null ? _ref1.service : void 0 : void 0))) {
            err = new Error("Bad service object found");
          }
          return cb(err);
        };
      })(this));
    };

    return WebServiceBinding;

  })(Base);

  SocialNetworkBinding = (function(_super) {
    __extends(SocialNetworkBinding, _super);

    function SocialNetworkBinding() {
      return SocialNetworkBinding.__super__.constructor.apply(this, arguments);
    }

    SocialNetworkBinding.prototype._service_obj_check = function(x) {
      var so;
      so = this.service_obj();
      return (x != null) && cieq(so.username, x.username) && cieq(so.name, x.name);
    };

    SocialNetworkBinding.prototype.service_obj = function() {
      return {
        name: this.service_name(),
        username: this.user.remote
      };
    };

    SocialNetworkBinding.prototype.is_remote_proof = function() {
      return true;
    };

    SocialNetworkBinding.single_occupancy = function() {
      return true;
    };

    SocialNetworkBinding.prototype.single_occupancy = function() {
      return SocialNetworkBinding.single_occupancy();
    };

    SocialNetworkBinding.normalize_name = function(n) {
      n = n.toLowerCase();
      if (n[0] === '@') {
        return n.slice(1);
      } else {
        return n;
      }
    };

    SocialNetworkBinding.prototype.normalize_name = function(n) {
      n || (n = this.user.remote);
      if (this.check_name(n)) {
        return SocialNetworkBinding.normalize_name(n);
      } else {
        return null;
      }
    };

    SocialNetworkBinding.prototype.check_inputs = function() {
      if (this.check_name(this.user.remote)) {
        return null;
      } else {
        return new Error("Bad remote_username given: " + this.user.remote);
      }
    };

    SocialNetworkBinding.prototype.to_key_value_pair = function() {
      return {
        key: this.service_name(),
        value: this.normalize_name()
      };
    };

    return SocialNetworkBinding;

  })(WebServiceBinding);

  has_non_ascii = function(s) {
    var buf, i, _i, _ref1;
    buf = new Buffer(s, 'utf8');
    for (i = _i = 0, _ref1 = buf.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
      if (buf.readUInt8(i) >= 128) {
        return true;
      }
    }
    return false;
  };

  GenericWebSiteBinding = (function(_super) {
    __extends(GenericWebSiteBinding, _super);

    function GenericWebSiteBinding(args) {
      this.remote_host = this.parse(args.remote_host);
      GenericWebSiteBinding.__super__.constructor.call(this, args);
    }

    GenericWebSiteBinding.parse = function(h, opts) {
      var n, o, protocol, ret;
      if (opts == null) {
        opts = {};
      }
      ret = null;
      if ((h != null) && ((h = h.toLowerCase()) != null) && ((o = urlmod.parse(h)) != null) && (o.hostname != null) && (!(o.path != null) || (o.path === '/')) && !(o.port != null)) {
        protocol = o.protocol || opts.protocol;
        if (protocol != null) {
          ret = {
            protocol: protocol,
            hostname: o.hostname
          };
          n = GenericWebSiteBinding.to_string(ret);
          if (has_non_ascii(n)) {
            console.error("Bug in urlmod found: found non-ascii in URL: " + n);
            ret = null;
          }
        }
      }
      return ret;
    };

    GenericWebSiteBinding.prototype.parse = function(h) {
      return GenericWebSiteBinding.parse(h);
    };

    GenericWebSiteBinding.prototype.to_key_value_pair = function() {
      return {
        key: this.remote_host.protocol.slice(0, -1),
        value: this.remote_host.hostname
      };
    };

    GenericWebSiteBinding.to_string = function(o) {
      return ([o.protocol, o.hostname].join('//')).toLowerCase();
    };

    GenericWebSiteBinding.normalize_name = function(s) {
      var o;
      if ((o = GenericWebSiteBinding.parse(s)) != null) {
        return GenericWebSiteBinding.to_string(o);
      } else {
        return null;
      }
    };

    GenericWebSiteBinding.check_name = function(h) {
      return GenericWebSiteBinding.parse(h) != null;
    };

    GenericWebSiteBinding.prototype.check_name = function(n) {
      return this.parse(n) != null;
    };

    GenericWebSiteBinding.single_occupancy = function() {
      return false;
    };

    GenericWebSiteBinding.prototype.single_occupancy = function() {
      return GenericWebSiteBinding.single_occupancy();
    };

    GenericWebSiteBinding.prototype.resource_id = function() {
      return this.to_string();
    };

    GenericWebSiteBinding.prototype.to_string = function() {
      return GenericWebSiteBinding.to_string(this.remote_host);
    };

    GenericWebSiteBinding.prototype._service_obj_check = function(x) {
      var so;
      so = this.service_obj();
      return (x != null) && (so != null) && cieq(so.protocol, x.protocol) && cieq(so.hostname, x.hostname);
    };

    GenericWebSiteBinding.prototype.service_obj = function() {
      return this.remote_host;
    };

    GenericWebSiteBinding.prototype.is_remote_proof = function() {
      return true;
    };

    GenericWebSiteBinding.prototype.proof_type = function() {
      return constants.proof_types.generic_web_site;
    };

    GenericWebSiteBinding.name_hint = function() {
      return "a valid hostname, like `my.site.com`";
    };

    GenericWebSiteBinding.prototype.check_inputs = function() {
      if (this.remote_host != null) {
        return null;
      } else {
        return new Error("Bad remote_host given");
      }
    };

    GenericWebSiteBinding.prototype.check_existing = function(proofs) {
      var check_data_json, v, _i, _len;
      if ((v = proofs.generic_web_site) != null) {
        for (_i = 0, _len = v.length; _i < _len; _i++) {
          check_data_json = v[_i].check_data_json;
          if (cieq(GenericWebSiteBinding.to_string(check_data_json), this.to_string())) {
            return new Error("A live proof for " + (this.to_string()) + " already exists");
          }
        }
      }
      return null;
    };

    return GenericWebSiteBinding;

  })(WebServiceBinding);

  DnsBinding = (function(_super) {
    __extends(DnsBinding, _super);

    function DnsBinding(args) {
      this.domain = this.parse(args.remote_host);
      DnsBinding.__super__.constructor.call(this, args);
    }

    DnsBinding.parse = function(h, opts) {
      var o, ret;
      if (opts == null) {
        opts = {};
      }
      ret = null;
      if (h != null) {
        if (h.indexOf("dns://") !== 0) {
          h = "dns://" + h;
        }
        if ((h != null) && ((h = h.toLowerCase()) != null) && ((o = urlmod.parse(h)) != null) && (o.hostname != null) && (!(o.path != null) || (o.path === '/')) && !(o.port != null)) {
          ret = o.hostname;
          if (has_non_ascii(ret)) {
            console.error("Bug in urlmod found: non-ASCII in done name: " + ret);
            ret = null;
          }
        }
      }
      return ret;
    };

    DnsBinding.prototype.to_key_value_pair = function() {
      return {
        key: "dns",
        value: this.domain
      };
    };

    DnsBinding.prototype.parse = function(h) {
      return DnsBinding.parse(h);
    };

    DnsBinding.to_string = function(o) {
      return o.domain;
    };

    DnsBinding.prototype.to_string = function() {
      return this.domain;
    };

    DnsBinding.prototype.normalize_name = function(s) {
      return DnsBinding.parse(s);
    };

    DnsBinding.single_occupancy = function() {
      return false;
    };

    DnsBinding.prototype.single_occupancy = function() {
      return DnsBinding.single_occupancy();
    };

    DnsBinding.prototype.resource_id = function() {
      return this.to_string();
    };

    DnsBinding.prototype._service_obj_check = function(x) {
      var so;
      so = this.service_obj();
      return (x != null) && (so != null) && cieq(so.protocol, x.protocol) && cieq(so.domain, x.domain);
    };

    DnsBinding.prototype.service_name = function() {
      return "dns";
    };

    DnsBinding.prototype.proof_type = function() {
      return constants.proof_types.dns;
    };

    DnsBinding.check_name = function(n) {
      return DnsBinding.parse(n) != null;
    };

    DnsBinding.prototype.check_name = function(n) {
      return DnsBinding.check_name(n);
    };

    DnsBinding.prototype.service_obj = function() {
      return {
        protocol: "dns",
        domain: this.domain
      };
    };

    DnsBinding.prototype.is_remote_proof = function() {
      return true;
    };

    DnsBinding.prototype.check_inputs = function() {
      if (this.domain) {
        return null;
      } else {
        return new Error("Bad domain given");
      }
    };

    DnsBinding.name_hint = function() {
      return "A DNS domain name, like maxk.org";
    };

    DnsBinding.prototype.check_existing = function(proofs) {
      var check_data_json, v, _i, _len;
      if ((v = proofs.dns != null)) {
        for (_i = 0, _len = v.length; _i < _len; _i++) {
          check_data_json = v[_i].check_data_json;
          if (cieq(GenericWebSiteBinding.to_string(check_data_json), this.to_string())) {
            return new Error("A live proof for " + (this.to_string()) + " already exists");
          }
        }
      }
      return null;
    };

    return DnsBinding;

  })(WebServiceBinding);

  TwitterBinding = (function(_super) {
    __extends(TwitterBinding, _super);

    function TwitterBinding() {
      return TwitterBinding.__super__.constructor.apply(this, arguments);
    }

    TwitterBinding.prototype.service_name = function() {
      return "twitter";
    };

    TwitterBinding.prototype.proof_type = function() {
      return constants.proof_types.twitter;
    };

    TwitterBinding.prototype.is_short = function() {
      return true;
    };

    TwitterBinding.check_name = function(n) {
      var ret;
      ret = (n == null) || ((n = n.toLowerCase()) == null) ? false : n.match(/^[a-z0-9_]{1,20}$/) ? true : false;
      return ret;
    };

    TwitterBinding.prototype.check_name = function(n) {
      return TwitterBinding.check_name(n);
    };

    TwitterBinding.name_hint = function() {
      return "alphanumerics, between 1 and 15 characters long";
    };

    return TwitterBinding;

  })(SocialNetworkBinding);

  KeybaseBinding = (function(_super) {
    __extends(KeybaseBinding, _super);

    function KeybaseBinding() {
      return KeybaseBinding.__super__.constructor.apply(this, arguments);
    }

    KeybaseBinding.prototype._service_obj_check = function(x) {
      return x == null;
    };

    KeybaseBinding.prototype.service_name = function() {
      return "keybase";
    };

    KeybaseBinding.prototype.proof_type = function() {
      return constants.proof_types.keybase;
    };

    KeybaseBinding.prototype.service_obj = function() {
      return null;
    };

    return KeybaseBinding;

  })(WebServiceBinding);

  GithubBinding = (function(_super) {
    __extends(GithubBinding, _super);

    function GithubBinding() {
      return GithubBinding.__super__.constructor.apply(this, arguments);
    }

    GithubBinding.prototype.service_name = function() {
      return "github";
    };

    GithubBinding.prototype.proof_type = function() {
      return constants.proof_types.github;
    };

    GithubBinding.check_name = function(n) {
      if ((n == null) || ((n = n.toLowerCase()) == null)) {
        return false;
      } else if (n.match(/^[a-z0-9][a-z0-9-]{0,38}$/)) {
        return true;
      } else {
        return false;
      }
    };

    GithubBinding.name_hint = function() {
      return "alphanumerics, between 1 and 39 characters long";
    };

    GithubBinding.prototype.check_name = function(n) {
      return GithubBinding.check_name(n);
    };

    return GithubBinding;

  })(SocialNetworkBinding);

  BitbucketBinding = (function(_super) {
    __extends(BitbucketBinding, _super);

    function BitbucketBinding() {
      return BitbucketBinding.__super__.constructor.apply(this, arguments);
    }

    BitbucketBinding.prototype.service_name = function() {
      return "bitbucket";
    };

    BitbucketBinding.prototype.proof_type = function() {
      return constants.proof_types.bitbucket;
    };

    BitbucketBinding.check_name = function(n) {
      if ((n == null) || ((n = n.toLowerCase()) == null)) {
        return false;
      } else if (n.match(/^[a-zA-Z0-9_\-]{0,31}/)) {
        return true;
      } else {
        return false;
      }
    };

    BitbucketBinding.name_hint = function() {
      return "alphanumerics, between 1 and 30 characters long";
    };

    BitbucketBinding.prototype.check_name = function(n) {
      return BitbucketBinding.check_name(n);
    };

    return BitbucketBinding;

  })(SocialNetworkBinding);

  RedditBinding = (function(_super) {
    __extends(RedditBinding, _super);

    function RedditBinding() {
      return RedditBinding.__super__.constructor.apply(this, arguments);
    }

    RedditBinding.prototype.service_name = function() {
      return "reddit";
    };

    RedditBinding.prototype.proof_type = function() {
      return constants.proof_types.reddit;
    };

    RedditBinding.check_name = function(n) {
      if ((n == null) || ((n = n.toLowerCase()) == null)) {
        return false;
      } else if (n.match(/^[a-z0-9_-]{3,20}$/)) {
        return true;
      } else {
        return false;
      }
    };

    RedditBinding.name_hint = function() {
      return "alphanumerics, between 3 and 20 characters long";
    };

    RedditBinding.prototype.check_name = function(n) {
      return RedditBinding.check_name(n);
    };

    return RedditBinding;

  })(SocialNetworkBinding);

  CoinbaseBinding = (function(_super) {
    __extends(CoinbaseBinding, _super);

    function CoinbaseBinding() {
      return CoinbaseBinding.__super__.constructor.apply(this, arguments);
    }

    CoinbaseBinding.prototype.service_name = function() {
      return "coinbase";
    };

    CoinbaseBinding.prototype.proof_type = function() {
      return constants.proof_types.coinbase;
    };

    CoinbaseBinding.check_name = function(n) {
      if ((n == null) || ((n = n.toLowerCase()) == null)) {
        return false;
      } else if (n.match(/^[a-z0-9_]{2,16}$/)) {
        return true;
      } else {
        return false;
      }
    };

    CoinbaseBinding.name_hint = function() {
      return "alphanumerics, between 2 and 16 characters long";
    };

    CoinbaseBinding.prototype.check_name = function(n) {
      return CoinbaseBinding.check_name(n);
    };

    return CoinbaseBinding;

  })(SocialNetworkBinding);

  HackerNewsBinding = (function(_super) {
    __extends(HackerNewsBinding, _super);

    function HackerNewsBinding() {
      return HackerNewsBinding.__super__.constructor.apply(this, arguments);
    }

    HackerNewsBinding.prototype.service_name = function() {
      return "hackernews";
    };

    HackerNewsBinding.prototype.proof_type = function() {
      return constants.proof_types.hackernews;
    };

    HackerNewsBinding.check_name = function(n) {
      if ((n == null) || ((n = n.toLowerCase()) == null)) {
        return false;
      } else if (n.match(/^[a-z0-9_-]{2,15}$/)) {
        return true;
      } else {
        return false;
      }
    };

    HackerNewsBinding.name_hint = function() {
      return "alphanumerics, between 2 and 15 characters long";
    };

    HackerNewsBinding.prototype.check_name = function(n) {
      return HackerNewsBinding.check_name(n);
    };

    HackerNewsBinding.normalize_name = function(n) {
      if (n[0] === '@') {
        return n.slice(1);
      } else {
        return n;
      }
    };

    HackerNewsBinding.prototype.normalize_name = function(n) {
      n || (n = this.user.remote);
      if (this.check_name(n)) {
        return HackerNewsBinding.normalize_name(n);
      } else {
        return null;
      }
    };

    HackerNewsBinding.prototype._service_obj_check = function(x) {
      var so;
      so = this.service_obj();
      return (x != null) && (so.username === x.username) && cieq(so.name, x.name);
    };

    return HackerNewsBinding;

  })(SocialNetworkBinding);

  exports.TwitterBinding = TwitterBinding;

  exports.RedditBinding = RedditBinding;

  exports.KeybaseBinding = KeybaseBinding;

  exports.GithubBinding = GithubBinding;

  exports.GenericWebSiteBinding = GenericWebSiteBinding;

  exports.CoinbaseBinding = CoinbaseBinding;

  exports.DnsBinding = DnsBinding;

  exports.HackerNewsBinding = HackerNewsBinding;

  exports.SocialNetworkBinding = SocialNetworkBinding;

  exports.BitbucketBinding = BitbucketBinding;

}).call(this);
