// Copyright (c) 2023, 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:io';
import 'dart:isolate';

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

Future<void> main() async {
  // A StreamChannel<T>, is in simplest terms, a wrapper around a Stream<T> and
  // a StreamSink<T>. For example, you can create a channel that wraps standard
  // IO:
  var stdioChannel = StreamChannel(stdin, stdout);
  stdioChannel.sink.add('Hello!\n'.codeUnits);

  // Like a Stream<T> can be transformed with a StreamTransformer<T>, a
  // StreamChannel<T> can be transformed with a StreamChannelTransformer<T>.
  // For example, we can handle standard input as strings:
  var stringChannel = stdioChannel
      .transform(StreamChannelTransformer.fromCodec(utf8))
      .transformStream(const LineSplitter());
  stringChannel.sink.add('world!\n');

  // You can implement StreamChannel<T> by extending StreamChannelMixin<T>, but
  // it's much easier to use a StreamChannelController<T>. A controller has two
  // StreamChannel<T> members: `local` and `foreign`. The creator of a
  // controller should work with the `local` channel, while the recipient should
  // work with the `foreign` channel, and usually will not have direct access to
  // the underlying controller.
  var ctrl = StreamChannelController<String>();
  ctrl.local.stream.listen((event) {
    // Do something useful here...
  });

  // You can also pipe events from one channel to another.
  ctrl
    ..foreign.pipe(stringChannel)
    ..local.sink.add('Piped!\n');
  await ctrl.local.sink.close();

  // The StreamChannel<T> interface provides several guarantees, which can be
  // found here:
  // https://pub.dev/documentation/stream_channel/latest/stream_channel/StreamChannel-class.html
  //
  // By calling `StreamChannel<T>.withGuarantees()`, you can create a
  // StreamChannel<T> that provides all guarantees.
  var dummyCtrl0 = StreamChannelController<String>();
  var guaranteedChannel = StreamChannel.withGuarantees(
      dummyCtrl0.foreign.stream, dummyCtrl0.foreign.sink);

  // To close a StreamChannel, use `sink.close()`.
  await guaranteedChannel.sink.close();

  // A MultiChannel<T> multiplexes multiple virtual channels across a single
  // underlying transport layer. For example, an application listening over
  // standard I/O can still support multiple clients if it has a mechanism to
  // separate events from different clients.
  //
  // A MultiChannel<T> splits events into numbered channels, which are
  // instances of VirtualChannel<T>.
  var dummyCtrl1 = StreamChannelController<String>();
  var multiChannel = MultiChannel<String>(dummyCtrl1.foreign);
  var channel1 = multiChannel.virtualChannel();
  await multiChannel.sink.close();

  // The client/peer should also create its own MultiChannel<T>, connected to
  // the underlying transport, use the corresponding ID's to handle events in
  // their respective channels. It is up to you how to communicate channel ID's
  // across different endpoints.
  var dummyCtrl2 = StreamChannelController<String>();
  var multiChannel2 = MultiChannel<String>(dummyCtrl2.foreign);
  var channel2 = multiChannel2.virtualChannel(channel1.id);
  await channel2.sink.close();
  await multiChannel2.sink.close();

  // Multiple instances of a Dart application can communicate easily across
  // `SendPort`/`ReceivePort` pairs by means of the `IsolateChannel<T>` class.
  // Typically, one endpoint will create a `ReceivePort`, and call the
  // `IsolateChannel.connectReceive` constructor. The other endpoint will be
  // given the corresponding `SendPort`, and then call
  // `IsolateChannel.connectSend`.
  var recv = ReceivePort();
  var recvChannel = IsolateChannel<void>.connectReceive(recv);
  var sendChannel = IsolateChannel<void>.connectSend(recv.sendPort);

  // You must manually close `IsolateChannel<T>` sinks, however.
  await recvChannel.sink.close();
  await sendChannel.sink.close();

  // You can use the `Disconnector` transformer to cause a channel to act as
  // though the remote end of its transport had disconnected.
  var disconnector = Disconnector<String>();
  var disconnectable = stringChannel.transform(disconnector);
  disconnectable.sink.add('Still connected!');
  await disconnector.disconnect();

  // Additionally:
  //   * The `DelegatingStreamController<T>` class can be extended to build a
  //     basis for wrapping other `StreamChannel<T>` objects.
  //   * The `jsonDocument` transformer converts events to/from JSON, using
  //     the `json` codec from `dart:convert`.
  //   * `package:json_rpc_2` directly builds on top of
  //     `package:stream_channel`, so any compatible transport can be used to
  //      create interactive client/server or peer-to-peer applications (i.e.
  //      language servers, microservices, etc.
}
