// 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 'package:stream_channel/stream_channel.dart';

/// Wraps a [StreamChannel] and handles logic that's shared between [Server],
/// [Client], and [Peer].
///
/// These classes don't provide the user direct access to a
/// [StreamSubscription]. Instead, they use the future returned by [listen] to
/// notify the user of the remote endpoint closing or producing an error.
class ChannelManager {
  /// The name of the component whose channel is wrapped (e.g. "Server").
  ///
  /// Used for error reporting.
  final String _name;

  /// The underlying channel.
  final StreamChannel _channel;

  /// Returns a [Future] that completes when the connection is closed.
  ///
  /// This is the same future that's returned by [listen].
  Future get done => _doneCompleter.future;
  final _doneCompleter = Completer.sync();

  /// Whether the underlying communication channel is closed.
  bool get isClosed => _doneCompleter.isCompleted;

  /// Whether [listen] has been called.
  bool _listenCalled = false;

  /// Whether [close] has been called.
  ///
  /// Note that [isClosed] tracks whether the underlying connection is closed,
  /// whereas this tracks only whether it was explicitly closed from this end.
  bool _closeCalled = false;

  ChannelManager(this._name, this._channel);

  /// Starts listening to the channel.
  ///
  /// The returned Future will complete when the input stream is closed. If the
  /// input stream emits an error, that will be piped to the returned Future.
  Future listen(void Function(dynamic) handleInput) {
    if (_listenCalled) {
      throw StateError('Can only call $_name.listen() once.');
    }
    _listenCalled = true;

    _channel.stream.listen(handleInput, onError: (error, stackTrace) {
      _doneCompleter.completeError(error, stackTrace);
      _channel.sink.close();
    }, onDone: () {
      if (!_doneCompleter.isCompleted) _doneCompleter.complete();
    }, cancelOnError: true);

    return done;
  }

  /// Emit [event].
  void add(event) {
    if (isClosed && !_closeCalled) return;
    _channel.sink.add(event);
  }

  /// Closes the channel.
  Future close() {
    _closeCalled = true;
    if (!_doneCompleter.isCompleted) {
      _doneCompleter.complete(_channel.sink.close());
    }
    return done;
  }
}
