// Generated by CoffeeScript 1.7.1
(function() {
  var WebSocketClient, listen, path, puncher, punching, raw, socket, _connection;

  path = require('path');

  raw = require('nw_raw-socket');

  WebSocketClient = require("nw_websocket").client;

  puncher = null;

  socket = null;

  punching = {};

  _connection = null;

  listen = function(port, url, callback) {
    var client;
    if (_connection) {
      _connection.close();
    }
    client = new WebSocketClient();
    client.on("connectFailed", function(error) {
      console.log("Connect Error: " + error.toString());
    });
    client.on("connect", function(connection) {
      _connection = connection;
      console.log("正在分配端口");
      connection.on("error", function(error) {
        return console.log(error);
      });
      connection.on("close", function() {
        return console.log("连接关闭");
      });
      return connection.on("message", function(message) {
        var operation, operator, remote_address, remote_port, _ref, _ref1;
        console.log(message.utf8Data);
        if (message.type === "utf8") {
          _ref = message.utf8Data.split(' ', 2), operator = _ref[0], operation = _ref[1];
          switch (operator) {
            case 'LISTEN':
              console.log("公网IP和端口: " + operation);
              return callback(operation);
            case 'PUNCH':
              _ref1 = operation.split(':'), remote_address = _ref1[0], remote_port = _ref1[1];
              remote_port = parseInt(remote_port);
              puncher(port, remote_port, remote_address, socket);
              return punching[operation] = setInterval(function() {
                return puncher(port, remote_port, remote_address, socket);
              }, 100);
            case 'PUNCHOK':
              clearInterval(punching[operation]);
              return delete punching[operation];
            default:
              throw 'unknown message';
          }
        }
      });
    });
    console.log("正在连接服务器");
    return client.connect(url, "shinkirou");
  };

  exports.listen = function(port, url, callback) {
    var WebSocketServer, e, http, server, wsServer;
    if (puncher) {
      return listen(port, url, callback);
    } else {
      try {
        socket = raw.createSocket({
          protocol: raw.Protocol.UDP
        });
        puncher = require('./puncher');
        return listen(port, url, callback);
      } catch (_error) {
        e = _error;
        WebSocketServer = require('nw_websocket').server;
        http = require('http');
        server = http.createServer();
        server.listen(5281, '127.0.0.1', function() {
          var wincmd;
          wincmd = require('node-windows');
          return wincmd.elevate("" + (path.join('bin', 'node')) + " app/js/puncher.js", {}, function(error, stdout, stderr) {
            if (error) {
              return callback(false);
            }
          });
        });
        wsServer = new WebSocketServer({
          httpServer: server,
          autoAcceptConnections: true
        });
        return wsServer.on('connect', function(connection) {
          listen(port, url, callback);
          puncher = function(local_port, remote_port, remote_address) {
            return connection.sendUTF("" + local_port + " " + remote_port + " " + remote_address);
          };
          return connection.on('close', function(reasonCode, description) {
            callback(false);
            server.close();
            return puncher = null;
          });
        });
      }
    }
  };

}).call(this);

//# sourceMappingURL=tunnel.map
