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

library web_socket_channel.html;

import 'dart:async';
import 'dart:html';
import 'dart:typed_data';

import 'package:async/async.dart';
import 'package:stream_channel/stream_channel.dart';

import 'src/channel.dart';
import 'src/exception.dart';

/// A [WebSocketChannel] that communicates using a `dart:html` [WebSocket].
class HtmlWebSocketChannel extends StreamChannelMixin
    implements WebSocketChannel {
  /// The underlying `dart:html` [WebSocket].
  final WebSocket _webSocket;

  String get protocol => _webSocket.protocol;

  int get closeCode => _closeCode;
  int _closeCode;

  String get closeReason => _closeReason;
  String _closeReason;

  /// The number of bytes of data that have been queued but not yet transmitted
  /// to the network.
  int get bufferedAmount => _webSocket.bufferedAmount;

  /// The close code set by the local user.
  ///
  /// To ensure proper ordering, this is stored until we get a done event on
  /// [_controller.local.stream].
  int _localCloseCode;

  /// The close reason set by the local user.
  ///
  /// To ensure proper ordering, this is stored until we get a done event on
  /// [_controller.local.stream].
  String _localCloseReason;

  Stream get stream => _controller.foreign.stream;
  final _controller =
      new StreamChannelController(sync: true, allowForeignErrors: false);

  WebSocketSink get sink => _sink;
  WebSocketSink _sink;

  /// Creates a new WebSocket connection.
  ///
  /// Connects to [url] using [new WebSocket] and returns a channel that can be
  /// used to communicate over the resulting socket. The [url] may be either a
  /// [String] or a [Uri]. The [protocols] parameter is the same as for
  /// [new WebSocket].
  ///
  /// The [binaryType] parameter controls what type is used for binary messages
  /// received by this socket. It defaults to [BinaryType.list], which causes
  /// binary messages to be delivered as [Uint8List]s. If it's
  /// [BinaryType.blob], they're delivered as [Blob]s instead.
  HtmlWebSocketChannel.connect(url,
      {Iterable<String> protocols, BinaryType binaryType})
      : this(new WebSocket(url.toString(), protocols)
          ..binaryType = (binaryType ?? BinaryType.list).value);

  /// Creates a channel wrapping [webSocket].
  HtmlWebSocketChannel(this._webSocket) {
    _sink = new _HtmlWebSocketSink(this);

    if (_webSocket.readyState == WebSocket.OPEN) {
      _listen();
    } else {
      // The socket API guarantees that only a single open event will be
      // emitted.
      _webSocket.onOpen.first.then((_) {
        _listen();
      });
    }

    // The socket API guarantees that only a single error event will be emitted,
    // and that once it is no open or message events will be emitted.
    _webSocket.onError.first.then((_) {
      _controller.local.sink.addError(
          new WebSocketChannelException("WebSocket connection failed."));
      _controller.local.sink.close();
    });

    _webSocket.onMessage.listen((event) {
      var data = event.data;
      if (data is ByteBuffer) data = data.asUint8List();
      _controller.local.sink.add(data);
    });

    // The socket API guarantees that only a single error event will be emitted,
    // and that once it is no other events will be emitted.
    _webSocket.onClose.first.then((event) {
      _closeCode = event.code;
      _closeReason = event.reason;
      _controller.local.sink.close();
    });
  }

  /// Pipes user events to [_webSocket].
  void _listen() {
    _controller.local.stream.listen((message) => _webSocket.send(message),
        onDone: () {
      // On Chrome and possibly other browsers, `null` can't be passed as the
      // default here. The actual arity of the function call must be correct or
      // it will fail.
      if (_localCloseCode != null && _localCloseReason != null) {
        _webSocket.close(_localCloseCode, _localCloseReason);
      } else if (_localCloseCode != null) {
        _webSocket.close(_localCloseCode);
      } else {
        _webSocket.close();
      }
    });
  }
}

/// A [WebSocketSink] that tracks the close code and reason passed to [close].
class _HtmlWebSocketSink extends DelegatingStreamSink implements WebSocketSink {
  /// The channel to which this sink belongs.
  final HtmlWebSocketChannel _channel;

  _HtmlWebSocketSink(HtmlWebSocketChannel channel)
      : _channel = channel,
        super(channel._controller.foreign.sink);

  Future close([int closeCode, String closeReason]) {
    _channel._localCloseCode = closeCode;
    _channel._localCloseReason = closeReason;
    return super.close();
  }
}

/// An enum for choosing what type [HtmlWebSocketChannel] emits for binary
/// messages.
class BinaryType {
  /// Tells the channel to emit binary messages as [Blob]s.
  static const blob = const BinaryType._("blob", "blob");

  /// Tells the channel to emit binary messages as [Uint8List]s.
  static const list = const BinaryType._("list", "arraybuffer");

  /// The name of the binary type, which matches its variable name.
  final String name;

  /// The value as understood by the underlying [WebSocket] API.
  final String value;

  const BinaryType._(this.name, this.value);

  String toString() => name;
}
