// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

class _WebSocketMessageType {
  static const int NONE = 0;
  static const int BINARY = 1;
  static const int TEXT = 2;
}


class _WebSocketOpcode {
  static const int CONTINUATION = 0;
  static const int TEXT = 1;
  static const int BINARY = 2;
  static const int RESERVED_3 = 3;
  static const int RESERVED_4 = 4;
  static const int RESERVED_5 = 5;
  static const int RESERVED_6 = 6;
  static const int RESERVED_7 = 7;
  static const int CLOSE = 8;
  static const int PING = 9;
  static const int PONG = 10;
  static const int RESERVED_B = 11;
  static const int RESERVED_C = 12;
  static const int RESERVED_D = 13;
  static const int RESERVED_E = 14;
  static const int RESERVED_F = 15;
}

/**
 * The web socket protocol processor handles the protocol byte stream
 * which is supplied through the [:update:] and [:closed:]
 * methods. As the protocol is processed the following callbacks are
 * called:
 *
 *   [:onMessageStart:]
 *   [:onMessageData:]
 *   [:onMessageEnd:]
 *   [:onClosed:]
 *   [:onError:]
 *
 */
class _WebSocketProtocolProcessor {
  static const int START = 0;
  static const int LEN_FIRST = 1;
  static const int LEN_REST = 2;
  static const int MASK = 3;
  static const int PAYLOAD = 4;
  static const int CLOSED = 5;
  static const int FAILURE = 6;

  _WebSocketProtocolProcessor() {
    _prepareForNextFrame();
    _currentMessageType = _WebSocketMessageType.NONE;
  }

  /**
   * Process data received from the underlying communication channel.
   */
  void update(List<int> buffer, int offset, int count) {
    int index = offset;
    int lastIndex = offset + count;
    try {
      if (_state == CLOSED) {
        throw new WebSocketException("Data on closed connection");
      }
      if (_state == FAILURE) {
        throw new WebSocketException("Data on failed connection");
      }
      while ((index < lastIndex) && _state != CLOSED && _state != FAILURE) {
        int byte = buffer[index];
        switch (_state) {
          case START:
            _fin = (byte & 0x80) != 0;
            _opcode = (byte & 0xF);
            switch (_opcode) {
            case _WebSocketOpcode.CONTINUATION:
              if (_currentMessageType == _WebSocketMessageType.NONE) {
                throw new WebSocketException("Protocol error");
              }
              break;

            case _WebSocketOpcode.TEXT:
              if (_currentMessageType != _WebSocketMessageType.NONE) {
                throw new WebSocketException("Protocol error");
              }
              _currentMessageType = _WebSocketMessageType.TEXT;
              if (onMessageStart !== null) {
                onMessageStart(_WebSocketMessageType.TEXT);
              }
              break;

            case _WebSocketOpcode.BINARY:
              if (_currentMessageType != _WebSocketMessageType.NONE) {
                throw new WebSocketException("Protocol error");
              }
              _currentMessageType = _WebSocketMessageType.BINARY;
              if (onMessageStart !== null) {
                onMessageStart(_WebSocketMessageType.BINARY);
              }
              break;

            case _WebSocketOpcode.CLOSE:
            case _WebSocketOpcode.PING:
            case _WebSocketOpcode.PONG:
              // Control frames cannot be fragmented.
              if (!_fin) throw new WebSocketException("Protocol error");
              break;

            default:
              throw new WebSocketException("Protocol error");
            }
            _state = LEN_FIRST;
            break;

          case LEN_FIRST:
            _masked = (byte & 0x80) != 0;
            _len = byte & 0x7F;
            if (_isControlFrame() && _len > 126) {
              throw new WebSocketException("Protocol error");
            }
            if (_len < 126) {
              _lengthDone();
            } else if (_len == 126) {
              _len = 0;
              _remainingLenBytes = 2;
              _state = LEN_REST;
            } else if (_len == 127) {
              _len = 0;
              _remainingLenBytes = 8;
              _state = LEN_REST;
            }
            break;

          case LEN_REST:
            _len = _len << 8 | byte;
            _remainingLenBytes--;
            if (_remainingLenBytes == 0) {
              _lengthDone();
            }
            break;

          case MASK:
            _maskingKey = _maskingKey << 8 | byte;
            _remainingMaskingKeyBytes--;
            if (_remainingMaskingKeyBytes == 0) {
              _maskDone();
            }
            break;

          case PAYLOAD:
            // The payload is not handled one byte at a time but in blocks.
            int payload;
            if (lastIndex - index <= _remainingPayloadBytes) {
              payload = lastIndex - index;
            } else {
              payload = _remainingPayloadBytes;
            }
            _remainingPayloadBytes -= payload;

            // Unmask payload if masked.
            if (_masked) {
              for (int i = 0; i < payload; i++) {
                int maskingByte =
                    ((_maskingKey >> ((3 - _unmaskingIndex) * 8)) & 0xFF);
                buffer[index + i] = buffer[index + i] ^ maskingByte;
                _unmaskingIndex = (_unmaskingIndex + 1) % 4;
              }
            }

            if (_isControlFrame()) {
              if (payload > 0) {
                // Allocate a buffer for collecting the control frame
                // payload if any.
                if (_controlPayload == null) {
                  _controlPayload = new List<int>();
                }
                _controlPayload.addAll(buffer.getRange(index, payload));
                index += payload;
              }

              if (_remainingPayloadBytes == 0) {
                _controlFrameEnd();
              }
            } else {
              switch (_currentMessageType) {
                case _WebSocketMessageType.NONE:
                  throw new WebSocketException("Protocol error");

                case _WebSocketMessageType.TEXT:
                case _WebSocketMessageType.BINARY:
                  if (onMessageData !== null) {
                    onMessageData(buffer, index, payload);
                  }
                  index += payload;
                  if (_remainingPayloadBytes == 0) {
                    _messageFrameEnd();
                  }
                  break;

                default:
                  throw new WebSocketException("Protocol error");
              }
            }

            // Hack - as we always do index++ below.
            index--;
        }

        // Move to the next byte.
        index++;
      }
    } catch (e) {
      if (onClosed !== null) onClosed(WebSocketStatus.PROTOCOL_ERROR,
                                      "Protocol error");
      _state = FAILURE;
    }
  }

  /**
   * Indicate that the underlying communication channel has been closed.
   */
  void closed() {
    if (_state == START || _state == CLOSED || _state == FAILURE) return;
    if (onClosed !== null) onClosed(WebSocketStatus.ABNORMAL_CLOSURE,
                                    "Connection closed unexpectedly");
    _state = CLOSED;
  }

  void _lengthDone() {
    if (_masked) {
      _state = MASK;
      _remainingMaskingKeyBytes = 4;
    } else {
      _remainingPayloadBytes = _len;
      _startPayload();
    }
  }

  void _maskDone() {
    _remainingPayloadBytes = _len;
    _startPayload();
  }

  void _startPayload() {
    // If there is no actual payload perform perform callbacks without
    // going through the PAYLOAD state.
    if (_remainingPayloadBytes == 0) {
      if (_isControlFrame()) {
        switch (_opcode) {
          case _WebSocketOpcode.CLOSE:
            if (onClosed !== null) onClosed(1005, "");
            _state = CLOSED;
            break;
          case _WebSocketOpcode.PING:
            if (onPing !== null) onPing(null);
            break;
          case _WebSocketOpcode.PONG:
            if (onPong !== null) onPong(null);
            break;
        }
        _prepareForNextFrame();
      } else {
        _messageFrameEnd();
      }
    } else {
      _state = PAYLOAD;
    }
  }

  void _messageFrameEnd() {
    if (_fin) {
      if (onMessageEnd !== null) onMessageEnd();
      _currentMessageType = _WebSocketMessageType.NONE;
    }
    _prepareForNextFrame();
  }

  void _controlFrameEnd() {
    switch (_opcode) {
      case _WebSocketOpcode.CLOSE:
        int status = WebSocketStatus.NO_STATUS_RECEIVED;
        String reason = "";
        if (_controlPayload.length > 0) {
          if (_controlPayload.length == 1) {
            throw new WebSocketException("Protocol error");
          }
          status = _controlPayload[0] << 8 | _controlPayload[1];
          if (status == WebSocketStatus.NO_STATUS_RECEIVED) {
            throw new WebSocketException("Protocol error");
          }
          if (_controlPayload.length > 2) {
            var decoder = _StringDecoders.decoder(Encoding.UTF_8);
            decoder.write(
                _controlPayload.getRange(2, _controlPayload.length - 2));
            reason = decoder.decoded();
          }
        }
        if (onClosed !== null) onClosed(status, reason);
        _state = CLOSED;
        break;

      case _WebSocketOpcode.PING:
        if (onPing !== null) onPing(_controlPayload);
        break;

      case _WebSocketOpcode.PONG:
        if (onPong !== null) onPong(_controlPayload);
        break;
    }
    _prepareForNextFrame();
  }

  bool _isControlFrame() {
    return _opcode == _WebSocketOpcode.CLOSE ||
           _opcode == _WebSocketOpcode.PING ||
           _opcode == _WebSocketOpcode.PONG;
  }

  void _prepareForNextFrame() {
    if (_state != CLOSED && _state != FAILURE) _state = START;
    _fin = null;
    _opcode = null;
    _len = null;
    _masked = null;
    _maskingKey = 0;
    _remainingLenBytes = null;
    _remainingMaskingKeyBytes = null;
    _remainingPayloadBytes = null;
    _unmaskingIndex = 0;
    _controlPayload = null;
  }

  int _state;
  bool _fin;
  int _opcode;
  int _len;
  bool _masked;
  int _maskingKey;
  int _remainingLenBytes;
  int _remainingMaskingKeyBytes;
  int _remainingPayloadBytes;
  int _unmaskingIndex;

  int _currentMessageType;
  List<int> _controlPayload;

  Function onMessageStart;
  Function onMessageData;
  Function onMessageEnd;
  Function onPing;
  Function onPong;
  Function onClosed;
}


class _WebSocketConnectionBase {
  void _socketConnected(Socket socket) {
    _socket = socket;
    _socket.onError = (e) => _socket.close();
  }

  void _startProcessing(List<int> unparsedData) {
    _WebSocketProtocolProcessor processor = new _WebSocketProtocolProcessor();
    processor.onMessageStart = _onWebSocketMessageStart;
    processor.onMessageData = _onWebSocketMessageData;
    processor.onMessageEnd = _onWebSocketMessageEnd;
    processor.onPing = _onWebSocketPing;
    processor.onPong = _onWebSocketPong;
    processor.onClosed = _onWebSocketClosed;
    if (unparsedData !== null) {
      processor.update(unparsedData, 0, unparsedData.length);
    }
    _socket.onData = () {
      int available = _socket.available();
      List<int> data = new List<int>(available);
      int read = _socket.readList(data, 0, available);
      processor.update(data, 0, read);
    };
    _socket.onClosed = () {
      processor.closed();
      if (_closeSent) {
        // Got socket close in response to close frame. Don't treat
        // that as an error.
        if (_closeTimer !== null) _closeTimer.cancel();
      } else {
        if (_onClosed !== null) _onClosed(WebSocketStatus.ABNORMAL_CLOSURE,
                                          "Unexpected close");
      }
      _socket.close();
    };
  }

  void set onMessage(void callback(Object message)) {
    _onMessage = callback;
  }

  void set onClosed(void callback(int status, String reason)) {
    _onClosed = callback;
  }

  send(message) {
    if (_closeSent) {
      throw new WebSocketException("Connection closed");
    }
    List<int> data;
    int opcode;
    if (message !== null) {
      if (message is String) {
        opcode = _WebSocketOpcode.TEXT;
        data = _StringEncoders.encoder(Encoding.UTF_8).encodeString(message);
      } else {
        if (message is !List<int>) {
          throw new ArgumentError(message);
        }
        opcode = _WebSocketOpcode.BINARY;
        data = message;
      }
    } else {
      opcode = _WebSocketOpcode.TEXT;
    }
    _sendFrame(opcode, data);
  }

  close([int status, String reason]) {
    if (status == WebSocketStatus.RESERVED_1004 ||
        status == WebSocketStatus.NO_STATUS_RECEIVED ||
        status == WebSocketStatus.RESERVED_1015) {
      throw new WebSocketException("Reserved status code $status");
    }

    if (_closeSent) return;
    List<int> data;
    if (status !== null) {
      data = new List<int>();
      data.add((status >> 8) & 0xFF);
      data.add(status & 0xFF);
      if (reason !== null) {
        data.addAll(
           _StringEncoders.encoder(Encoding.UTF_8).encodeString(reason));
      }
    }
    _sendFrame(_WebSocketOpcode.CLOSE, data);

    if (_closeReceived) {
      // Close the socket when the close frame has been sent - if it
      // does not take too long.
      _socket.outputStream.close();
      _socket.outputStream.onClosed = () {
        if (_closeTimer !== null) _closeTimer.cancel();
        _socket.close();
      };
      _closeTimer = new Timer(5000, (t) {
        _socket.close();
      });
    } else {
      // Half close the socket and expect a close frame in response
      // before closing the socket. If a close frame does not arrive
      // within a reasonable amount of time just close the socket.
      _socket.outputStream.close();
      _closeTimer = new Timer(5000, (t) {
        _socket.close();
      });
    }
    _closeSent = true;
  }

  int get hashCode => _hash;

  _onWebSocketMessageStart(int type) {
    _currentMessageType = type;
    if (_currentMessageType == _WebSocketMessageType.TEXT) {
      _decoder = _StringDecoders.decoder(Encoding.UTF_8);
    } else {
      _outputStream = new ListOutputStream();
    }
  }

  _onWebSocketMessageData(List<int> buffer, int offset, int count) {
    if (_currentMessageType == _WebSocketMessageType.TEXT) {
      _decoder.write(buffer.getRange(offset, count));
    } else {
      _outputStream.write(buffer.getRange(offset, count));
    }
  }

  _onWebSocketMessageEnd() {
    if (_onMessage !== null) {
      if (_currentMessageType == _WebSocketMessageType.TEXT) {
        _onMessage(_decoder.decoded());
      } else {
        _onMessage(_outputStream.read());
      }
    }
    _decoder = null;
    _outputStream = null;
  }

  _onWebSocketPing(List<int> payload) {
    _sendFrame(_WebSocketOpcode.PONG, payload);
  }

  _onWebSocketPong(List<int> payload) {
    // Currently pong messages are ignored.
  }

  _onWebSocketClosed(int status, String reason) {
    _closeReceived = true;
    if (_onClosed !== null) _onClosed(status, reason);
    if (_closeSent) {
      // Got close frame in response to close frame. Now close the socket.
      if (_closeTimer !== null) _closeTimer.cancel();
      _socket.close();
    } else {
      if (status != WebSocketStatus.NO_STATUS_RECEIVED) {
        close(status);
      } else {
        close();
      }
    }
  }

  _sendFrame(int opcode, [List<int> data]) {
    bool mask = false;  // Masking not implemented for server.
    int dataLength = data == null ? 0 : data.length;
    // Determine the header size.
    int headerSize = (mask) ? 6 : 2;
    if (dataLength > 65535) {
      headerSize += 8;
    } else if (dataLength > 125) {
      headerSize += 2;
    }
    List<int> header = new List<int>(headerSize);
    int index = 0;
    // Set FIN and opcode.
    header[index++] = 0x80 | opcode;
    // Determine size and position of length field.
    int lengthBytes = 1;
    int firstLengthByte = 1;
    if (dataLength > 65535) {
      header[index++] = 127;
      lengthBytes = 8;
    } else if (dataLength > 125) {
      header[index++] = 126;
      lengthBytes = 2;
    }
    // Write the length in network byte order into the header.
    for (int i = 0; i < lengthBytes; i++) {
      header[index++] = dataLength >> (((lengthBytes - 1) - i) * 8) & 0xFF;
    }
    assert(index == headerSize);
    _socket.outputStream.write(header);
    if (data !== null) {
      _socket.outputStream.write(data);
    }
  }

  Socket _socket;
  Timer _closeTimer;
  int _hash;

  Function _onMessage;
  Function _onClosed;

  int _currentMessageType = _WebSocketMessageType.NONE;
  _StringDecoder _decoder;
  ListOutputStream _outputStream;
  bool _closeReceived = false;
  bool _closeSent = false;
}


class _WebSocketConnection
    extends _WebSocketConnectionBase implements WebSocketConnection {
  _WebSocketConnection(DetachedSocket detached) {
    _hash = detached.socket.hashCode;
    _socketConnected(detached.socket);
    _startProcessing(detached.unparsedData);
  }
}


class _WebSocketHandler implements WebSocketHandler {
  void onRequest(HttpRequest request, HttpResponse response) {
    // Check that this is a web socket upgrade.
    if (!_isWebSocketUpgrade(request)) {
      response.statusCode = HttpStatus.BAD_REQUEST;
      response.outputStream.close();
      return;
    }

    // Send the upgrade response.
    response.statusCode = HttpStatus.SWITCHING_PROTOCOLS;
    response.headers.add(HttpHeaders.CONNECTION, "Upgrade");
    response.headers.add(HttpHeaders.UPGRADE, "websocket");
    String key = request.headers.value("Sec-WebSocket-Key");
    SHA1 sha1 = new SHA1();
    sha1.update("$key$_webSocketGUID".charCodes);
    String accept = _Base64._encode(sha1.digest());
    response.headers.add("Sec-WebSocket-Accept", accept);
    response.contentLength = 0;

    // Upgrade the connection and get the underlying socket.
    WebSocketConnection conn =
        new _WebSocketConnection(response.detachSocket());
    if (_onOpen !== null) _onOpen(conn);
  }

  void set onOpen(callback(WebSocketConnection connection)) {
    _onOpen = callback;
  }

  bool _isWebSocketUpgrade(HttpRequest request) {
    if (request.method != "GET") {
      return false;
    }
    if (request.headers[HttpHeaders.CONNECTION] == null) {
      return false;
    }
    bool isUpgrade = false;
    request.headers[HttpHeaders.CONNECTION].forEach((String value) {
      if (value.toLowerCase() == "upgrade") isUpgrade = true;
    });
    if (!isUpgrade) return false;
    String upgrade = request.headers.value(HttpHeaders.UPGRADE);
    if (upgrade == null || upgrade.toLowerCase() != "websocket") {
      return false;
    }
    String version = request.headers.value("Sec-WebSocket-Version");
    if (version == null || version != "13") {
      return false;
    }
    String key = request.headers.value("Sec-WebSocket-Key");
    if (key == null) {
      return false;
    }
    return true;
  }

  Function _onOpen;
}


class _WebSocketClientConnection
    extends _WebSocketConnectionBase implements WebSocketClientConnection {
  _WebSocketClientConnection(HttpClientConnection this._conn,
                             [List<String> protocols]) {
    _conn.onRequest = _onHttpClientRequest;
    _conn.onResponse = _onHttpClientResponse;
    _conn.onError = (e) {
      if (_onClosed !== null) {
        _onClosed(WebSocketStatus.ABNORMAL_CLOSURE, "$e");
      }
    };

    // Generate the nonce now as it is also used to set the hash code.
    _generateNonceAndHash();
  }

  void set onRequest(void callback(HttpClientRequest request)) {
    _onRequest = callback;
  }

  void set onOpen(void callback()) {
    _onOpen = callback;
  }

  void set onNoUpgrade(void callback(HttpClientResponse request)) {
    _onNoUpgrade = callback;
  }

  void _onHttpClientRequest(HttpClientRequest request) {
    if (_onRequest !== null) {
      _onRequest(request);
    }
    // Setup the initial handshake.
    request.headers.add(HttpHeaders.CONNECTION, "upgrade");
    request.headers.set(HttpHeaders.UPGRADE, "websocket");
    request.headers.set("Sec-WebSocket-Key", _nonce);
    request.headers.set("Sec-WebSocket-Version", "13");
    request.contentLength = 0;
    request.outputStream.close();
  }

  void _onHttpClientResponse(HttpClientResponse response) {
    if (response.statusCode != HttpStatus.SWITCHING_PROTOCOLS) {
      if (_onNoUpgrade !== null) {
        _onNoUpgrade(response);
      } else {
        _conn.detachSocket().socket.close();
        throw new WebSocketException("Protocol upgrade refused");
      }
      return;
    }

    if (!_isWebSocketUpgrade(response)) {
      _conn.detachSocket().socket.close();
      throw new WebSocketException("Protocol upgrade failed");
      return;
    }

    // Connection upgrade successful.
    DetachedSocket detached = _conn.detachSocket();
    _socketConnected(detached.socket);
    if (_onOpen !== null) _onOpen();
    _startProcessing(detached.unparsedData);
  }

  void _generateNonceAndHash() {
    Random random = new Random();
    assert(_nonce == null);
    void intToBigEndianBytes(int value, List<int> bytes, int offset) {
      bytes[offset] = (value >> 24) & 0xFF;
      bytes[offset + 1] = (value >> 16) & 0xFF;
      bytes[offset + 2] = (value >> 8) & 0xFF;
      bytes[offset + 3] = value & 0xFF;
    }

    // Generate 16 random bytes. Use the last four bytes for the hash code.
    List<int> nonce = new List<int>(16);
    for (int i = 0; i < 4; i++) {
      int r = random.nextInt(0x100000000);
      intToBigEndianBytes(r, nonce, i * 4);
    }
    _nonce = _Base64._encode(nonce);
    _hash = random.nextInt(0x100000000);
  }

  bool _isWebSocketUpgrade(HttpClientResponse response) {
    if (response.headers[HttpHeaders.CONNECTION] == null) {
      return false;
    }
    bool isUpgrade = false;
    response.headers[HttpHeaders.CONNECTION].forEach((String value) {
      if (value.toLowerCase() == "upgrade") isUpgrade = true;
    });
    if (!isUpgrade) return false;
    String upgrade = response.headers.value(HttpHeaders.UPGRADE);
    if (upgrade == null || upgrade.toLowerCase() != "websocket") {
      return false;
    }
    String accept = response.headers.value("Sec-WebSocket-Accept");
    if (accept == null) {
      return false;
    }
    SHA1 sha1 = new SHA1();
    sha1.update("$_nonce$_webSocketGUID".charCodes);
    List<int> expectedAccept = sha1.digest();
    List<int> receivedAccept = _Base64._decode(accept);
    if (expectedAccept.length != receivedAccept.length) return false;
    for (int i = 0; i < expectedAccept.length; i++) {
      if (expectedAccept[i] != receivedAccept[i]) return false;
    }
    return true;
  }

  Function _onRequest;
  Function _onOpen;
  Function _onNoUpgrade;
  HttpClientConnection _conn;
  String _nonce;
}


class _WebSocket implements WebSocket {
  _WebSocket(String url, [protocols]) {
    Uri uri = new Uri.fromString(url);
    if (uri.scheme != "ws") {
      throw new WebSocketException("Unsupported URL scheme ${uri.scheme}");
    }
    if (uri.userInfo != "") {
      throw new WebSocketException("Unsupported user info ${uri.userInfo}");
    }
    int port = uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : uri.port;
    String path = uri.path;
    if (path.length == 0) path = "/";
    if (uri.query != "") {
      if (uri.fragment != "") {
        path = "${path}?${uri.query}#${uri.fragment}";
      } else {
        path = "${path}?${uri.query}";
      }
    }

    HttpClient client = new HttpClient();
    HttpClientConnection conn = client.open("GET", uri.domain, port, path);
    if (protocols is String) protocols = [protocols];
    _wsconn = new WebSocketClientConnection(conn, protocols);
    _wsconn.onOpen = () {
      // HTTP client not needed after socket have been detached.
      client.shutdown();
      client = null;
      _readyState = WebSocket.OPEN;
      if (_onopen !== null) _onopen();
    };
    _wsconn.onMessage = (message) {
      if (_onmessage !== null) {
        _onmessage(new _WebSocketMessageEvent(message));
      }
    };
    _wsconn.onClosed = (status, reason) {
      _readyState = WebSocket.CLOSED;
      if (_onclose !== null) {
        _onclose(new _WebSocketCloseEvent(true, status, reason));
      }
    };
    _wsconn.onNoUpgrade = (response) {
      if (_onclose !== null) {
        _onclose(
            new _WebSocketCloseEvent(true,
                                     WebSocketStatus.ABNORMAL_CLOSURE,
                                     "Connection not upgraded"));
      }
    };
  }

  int get readyState => _readyState;
  int get bufferedAmount => 0;

  void set onopen(Function callback) {
    _onopen = callback;
  }

  void set onerror(Function callback) {}

  void set onclose(Function callback) {
    _onclose = callback;
  }

  String get extensions => null;
  String get protocol => null;

  void close(int code, String reason) {
    if (_readyState < WebSocket.CLOSING) _readyState = WebSocket.CLOSING;
    _wsconn.close(code, reason);
  }

  void set onmessage(Function callback) {
    _onmessage = callback;
  }

  void send(data) {
    _wsconn.send(data);
  }

  WebSocketClientConnection _wsconn;
  int _readyState = WebSocket.CONNECTING;
  Function _onopen;
  Function _onclose;
  Function _onmessage;
}


class _WebSocketMessageEvent implements MessageEvent {
  _WebSocketMessageEvent(this._data);
  get data => _data;
  var _data;
}


class _WebSocketCloseEvent implements CloseEvent {
  _WebSocketCloseEvent(this._wasClean, this._code, this._reason);
  bool get wasClean => _wasClean;
  int get code => _code;
  String get reason => _reason;
  bool _wasClean;
  int _code;
  String _reason;
}
