// 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.

import 'dart:async';
import 'dart:convert';
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);

  void addUtf8Text(List<int> bytes) => super.add(UTF8.decode(bytes));

  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;
}
