(function() {
  var Auth, EventEmitter, Forge, Parser, Promise, Protocol, RollingCounter, ServiceMap, Socket, crypto, debug,
    __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; };

  crypto = require('crypto');

  EventEmitter = require('events').EventEmitter;

  Promise = require('bluebird');

  Forge = require('node-forge');

  debug = require('debug')('adb:tcpusb:socket');

  Parser = require('../parser');

  Protocol = require('../protocol');

  Auth = require('../auth');

  ServiceMap = require('./servicemap');

  RollingCounter = require('./rollingcounter');

  Socket = (function(_super) {
    var AUTH_RSAPUBLICKEY, AUTH_SIGNATURE, AUTH_TOKEN, A_AUTH, A_CLSE, A_CNXN, A_OKAY, A_OPEN, A_SYNC, A_WRTE, TOKEN_LENGTH, UINT32_MAX;

    __extends(Socket, _super);

    A_SYNC = 0x434e5953;

    A_CNXN = 0x4e584e43;

    A_OPEN = 0x4e45504f;

    A_OKAY = 0x59414b4f;

    A_CLSE = 0x45534c43;

    A_WRTE = 0x45545257;

    A_AUTH = 0x48545541;

    UINT32_MAX = 0xFFFFFFFF;

    AUTH_TOKEN = 1;

    AUTH_SIGNATURE = 2;

    AUTH_RSAPUBLICKEY = 3;

    TOKEN_LENGTH = 20;

    function Socket(client, serial, socket, options) {
      var _base;
      this.client = client;
      this.serial = serial;
      this.socket = socket;
      this.options = options != null ? options : {};
      (_base = this.options).auth || (_base.auth = Promise.resolve(true));
      this.ended = false;
      this.parser = new Parser(this.socket);
      this.version = 1;
      this.maxPayload = 4096;
      this.authorized = false;
      this.syncToken = new RollingCounter(UINT32_MAX);
      this.remoteId = new RollingCounter(UINT32_MAX);
      this.services = new ServiceMap;
      this.remoteAddress = this.socket.remoteAddress;
      this.token = null;
      this.signature = null;
      this._inputLoop();
    }

    Socket.prototype.end = function() {
      if (!this.ended) {
        this.socket.end();
        this.services.end();
        this.emit('end');
        this.ended = true;
      }
      return this;
    };

    Socket.prototype._inputLoop = function() {
      return this._readMessage().then((function(_this) {
        return function(message) {
          return _this._route(message);
        };
      })(this)).then((function(_this) {
        return function() {
          return setImmediate(_this._inputLoop.bind(_this));
        };
      })(this))["catch"](Parser.PrematureEOFError, (function(_this) {
        return function() {
          return _this.end();
        };
      })(this))["catch"]((function(_this) {
        return function(err) {
          debug("Error: " + err.message);
          _this.emit('error', err);
          return _this.end();
        };
      })(this));
    };

    Socket.prototype._readMessage = function() {
      return this.parser.readBytes(24).then(function(header) {
        return {
          command: header.readUInt32LE(0),
          arg0: header.readUInt32LE(4),
          arg1: header.readUInt32LE(8),
          length: header.readUInt32LE(12),
          check: header.readUInt32LE(16),
          magic: header.readUInt32LE(20)
        };
      }).then((function(_this) {
        return function(message) {
          return _this.parser.readBytes(message.length).then(function(data) {
            message.data = data;
            return message;
          });
        };
      })(this)).then((function(_this) {
        return function(message) {
          return _this._validateMessage(message);
        };
      })(this));
    };

    Socket.prototype._route = function(message) {
      if (this.ended) {
        return;
      }
      this.emit('userActivity', message);
      switch (message.command) {
        case A_SYNC:
          return this._handleSyncMessage(message);
        case A_CNXN:
          return this._handleConnectionMessage(message);
        case A_OPEN:
          return this._handleOpenMessage(message);
        case A_OKAY:
          return this._handleOkayMessage(message);
        case A_CLSE:
          return this._handleCloseMessage(message);
        case A_WRTE:
          return this._handleWriteMessage(message);
        case A_AUTH:
          return this._handleAuthMessage(message);
        default:
          return this.emit('error', new Error("Unknown command " + message.command));
      }
    };

    Socket.prototype._handleSyncMessage = function(message) {
      return this._writeHeader(A_SYNC, 1, this.syncToken.next(), 0);
    };

    Socket.prototype._handleConnectionMessage = function(message) {
      debug('A_CNXN', message);
      return this._createToken().then((function(_this) {
        return function(token) {
          _this.token = token;
          return _this._writeMessage(A_AUTH, AUTH_TOKEN, 0, _this.token);
        };
      })(this));
    };

    Socket.prototype._handleAuthMessage = function(message) {
      debug('A_AUTH', message);
      switch (message.arg0) {
        case AUTH_SIGNATURE:
          if (!this.signature) {
            this.signature = message.data;
          }
          return this._writeMessage(A_AUTH, AUTH_TOKEN, 0, this.token);
        case AUTH_RSAPUBLICKEY:
          return Auth.parsePublicKey(message.data.slice(0, -1)).then((function(_this) {
            return function(key) {
              var digest, sig;
              digest = _this.token.toString('binary');
              sig = _this.signature.toString('binary');
              if (key.verify(digest, sig)) {
                return _this.options.auth(key).then(function() {
                  return _this._deviceId().then(function(id) {
                    _this.authorized = true;
                    return _this._writeMessage(A_CNXN, _this.version, _this.maxPayload, "device::" + id);
                  });
                })["catch"](function(err) {
                  return _this.end();
                });
              } else {
                return _this.end();
              }
            };
          })(this));
        default:
          return this.end();
      }
    };

    Socket.prototype._handleOpenMessage = function(message) {
      var command, localId, remoteId, service;
      if (!this.authorized) {
        return;
      }
      debug('A_OPEN', message);
      localId = message.arg0;
      remoteId = this.remoteId.next();
      service = message.data.slice(0, -1);
      command = service.toString().split(':', 1)[0];
      return this.client.transport(this.serial).then((function(_this) {
        return function(transport) {
          var parser, pump;
          if (_this.ended) {
            return;
          }
          debug("Calling " + service);
          _this.services.put(remoteId, transport);
          transport.write(Protocol.encodeData(service));
          parser = transport.parser;
          pump = function() {
            return new Promise(function(resolve, reject) {
              var maybeRead, out;
              out = parser.raw();
              maybeRead = function() {
                var chunk, _results;
                _results = [];
                while (chunk = _this._readChunk(out)) {
                  _results.push(_this._writeMessage(A_WRTE, remoteId, localId, chunk));
                }
                return _results;
              };
              out.on('readable', maybeRead);
              return out.on('end', resolve);
            });
          };
          parser.readAscii(4).then(function(reply) {
            switch (reply) {
              case Protocol.OKAY:
                _this._writeHeader(A_OKAY, remoteId, localId);
                return pump();
              case Protocol.FAIL:
                return parser.readError();
              default:
                return parser.unexpected(reply, 'OKAY or FAIL');
            }
          })["catch"](Parser.PrematureEOFError, function() {
            return true;
          })["finally"](function() {
            return _this._close(remoteId, localId);
          })["catch"](Parser.FailError, function(err) {
            debug("Unable to open transport: " + err);
            return _this.end();
          });
        };
      })(this));
    };

    Socket.prototype._handleOkayMessage = function(message) {
      var localId, remoteId;
      if (!this.authorized) {
        return;
      }
      debug('A_OKAY', message);
      localId = message.arg0;
      return remoteId = message.arg1;
    };

    Socket.prototype._handleCloseMessage = function(message) {
      var localId, remoteId;
      if (!this.authorized) {
        return;
      }
      debug('A_CLSE', message);
      localId = message.arg0;
      remoteId = message.arg1;
      return this._close(remoteId, localId);
    };

    Socket.prototype._handleWriteMessage = function(message) {
      var localId, remote, remoteId;
      if (!this.authorized) {
        return;
      }
      debug('A_WRTE', message);
      localId = message.arg0;
      remoteId = message.arg1;
      if (remote = this.services.get(remoteId)) {
        remote.write(message.data);
        this._writeHeader(A_OKAY, remoteId, localId);
      } else {
        debug("A_WRTE to unknown socket pair " + localId + "/" + remoteId);
      }
      return true;
    };

    Socket.prototype._close = function(remoteId, localId) {
      var remote;
      if (remote = this.services.remove(remoteId)) {
        remote.end();
        return this._writeHeader(A_CLSE, remoteId, localId);
      }
    };

    Socket.prototype._writeHeader = function(command, arg0, arg1, length, checksum) {
      var header;
      if (this.ended) {
        return;
      }
      header = new Buffer(24);
      header.writeUInt32LE(command, 0);
      header.writeUInt32LE(arg0 || 0, 4);
      header.writeUInt32LE(arg1 || 0, 8);
      header.writeUInt32LE(length || 0, 12);
      header.writeUInt32LE(checksum || 0, 16);
      header.writeUInt32LE(this._magic(command), 20);
      return this.socket.write(header);
    };

    Socket.prototype._writeMessage = function(command, arg0, arg1, data) {
      if (this.ended) {
        return;
      }
      if (!Buffer.isBuffer(data)) {
        data = new Buffer(data);
      }
      this._writeHeader(command, arg0, arg1, data.length, this._checksum(data));
      return this.socket.write(data);
    };

    Socket.prototype._validateMessage = function(message) {
      if (message.magic !== this._magic(message.command)) {
        throw new Error("Command failed magic check");
      }
      if (message.check !== this._checksum(message.data)) {
        throw new Error("Message checksum doesn't match received message");
      }
      return message;
    };

    Socket.prototype._readChunk = function(stream) {
      return stream.read(this.maxPayload) || stream.read();
    };

    Socket.prototype._checksum = function(data) {
      var char, sum, _i, _len;
      if (!Buffer.isBuffer(data)) {
        throw new Error("Unable to calculate checksum of non-Buffer");
      }
      sum = 0;
      for (_i = 0, _len = data.length; _i < _len; _i++) {
        char = data[_i];
        sum += char;
      }
      return sum;
    };

    Socket.prototype._magic = function(command) {
      return (command ^ 0xffffffff) >>> 0;
    };

    Socket.prototype._createToken = function() {
      return Promise.promisify(crypto.randomBytes)(TOKEN_LENGTH);
    };

    Socket.prototype._deviceId = function() {
      return this.client.getProperties(this.serial).then(function(properties) {
        var prop;
        return ((function() {
          var _i, _len, _ref, _results;
          _ref = ['ro.product.name', 'ro.product.model', 'ro.product.device'];
          _results = [];
          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
            prop = _ref[_i];
            _results.push("" + prop + "=" + properties[prop] + ";");
          }
          return _results;
        })()).join('');
      });
    };

    return Socket;

  })(EventEmitter);

  module.exports = Socket;

}).call(this);
