// Copyright (c) 2013, 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.

part of dart.io;

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 index = 0;
    int lastIndex = buffer.length;
    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--;
            break;
        }

        // 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);
    }
    _socket.onData = () {
      processor.update(_socket.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(const Duration(seconds: 5), _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(const Duration(seconds: 5), _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>.fixedLength(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.add("$key$_webSocketGUID".charCodes);
    String accept = _Base64._encode(sha1.close());
    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");
    }

    // 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>.fixedLength(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.add("$_nonce$_webSocketGUID".charCodes);
    List<int> expectedAccept = sha1.close();
    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 = Uri.parse(url);
    if (uri.scheme != "ws" && uri.scheme != "wss") {
      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();
    bool secure = (uri.scheme == 'wss');
    HttpClientConnection conn = client.openUrl("GET",
        new Uri.fromComponents(scheme: secure ? "https" : "http",
                               domain: uri.domain,
                               port: port,
                               path: 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;
}
