// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';

typedef BrookCallback<T> = void Function(T event);

/// A source of events of type T.
///
/// This is a light-weight stream, hence the name of the class.
///
/// Listeners cannot be registered multiple times simultaneously.
class Brook<T> {
  Brook();

  final Set<BrookCallback<T>> _listeners = <BrookCallback<T>>{};

  void addListener(BrookCallback<T> listener) {
    assert(!_listeners.contains(listener));
    _listeners.add(listener);
  }

  void removeListener(BrookCallback<T> listener) {
    assert(_listeners.contains(listener));
    _listeners.remove(listener);
  }
}

/// A place to send events of type T.
///
/// Instances of this class can be given to consumers, as the type [Brook].
/// This allows consumers to register for events without being able to send
/// events.
class BrookSink<T> extends Brook<T> {
  BrookSink();

  void send(T event) {
    final List<BrookCallback<T>> frozenListeners = _listeners.toList();
    for (final BrookCallback<T> listener in frozenListeners) {
      try {
        if (_listeners.contains(listener)) {
          listener(event);
        }
      } catch (exception, stack) {
        FlutterError.reportError(
          FlutterErrorDetails(
            exception: exception,
            stack: stack,
            library: 'Flutter Dashboard',
            context: ErrorDescription('while sending event'),
            informationCollector: () sync* {
              yield DiagnosticsProperty<BrookSink<T>>(
                'The $runtimeType sending the event was',
                this,
                style: DiagnosticsTreeStyle.errorProperty,
              );
              yield DiagnosticsProperty<T>(
                'The $T event was',
                event,
                style: DiagnosticsTreeStyle.errorProperty,
              );
            },
          ),
        );
      }
    }
  }
}

class ErrorSink extends BrookSink<String> {
  ErrorSink();

  @override
  void send(String event) {
    // TODO(ianh): log errors to a service as well, https://github.com/flutter/flutter/issues/52697
    debugPrint(event); // to allow for copy/paste
    super.send(event);
  }
}
