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

part of dart.io;

/**
 * A combined byte and text output.
 *
 * An [IOSink] combines a [StreamSink] of bytes with a [StringSink],
 * and allows easy output of both bytes and text.
 *
 * Writing text ([write]) and adding bytes ([add]) may be interleaved freely.
 *
 * While a stream is being added using [addStream], any further attempts
 * to add or write to the [IOSink] will fail until the [addStream] completes.
 *
 * It is an error to add data to the [IOSink] after the sink is closed.
 */
abstract class IOSink implements StreamSink<List<int>>, StringSink {
  /**
   * Create an [IOSink] that outputs to a [target] [StreamConsumer] of bytes.
   *
   * Text written to [StreamSink] methods is encoded to bytes using [encoding]
   * before being output on [target].
   */
  factory IOSink(StreamConsumer<List<int>> target, {Encoding encoding: utf8}) =>
      new _IOSinkImpl(target, encoding);

  /**
   * The [Encoding] used when writing strings. Depending on the
   * underlying consumer this property might be mutable.
   */
  late Encoding encoding;

  /**
   * Adds byte [data] to the target consumer, ignoring [encoding].
   *
   * The [encoding] does not apply to this method, and the `data` list is passed
   * directly to the target consumer as a stream event.
   *
   * This function must not be called when a stream is currently being added
   * using [addStream].
   *
   * This operation is non-blocking. See [flush] or [done] for how to get any
   * errors generated by this call.
   *
   * The data list should not be modified after it has been passed to `add`.
   */
  void add(List<int> data);

  /**
   * Converts [obj] to a String by invoking [Object.toString] and
   * [add]s the encoding of the result to the target consumer.
   *
   * This operation is non-blocking. See [flush] or [done] for how to get any
   * errors generated by this call.
   */
  void write(Object? obj);

  /**
   * Iterates over the given [objects] and [write]s them in sequence.
   *
   * If [separator] is provided, a `write` with the `separator` is performed
   * between any two elements of objects.
   *
   * This operation is non-blocking. See [flush] or [done] for how to get any
   * errors generated by this call.
   */
  void writeAll(Iterable objects, [String separator = ""]);

  /**
   * Converts [obj] to a String by invoking [Object.toString] and
   * writes the result to `this`, followed by a newline.
   *
   * This operation is non-blocking. See [flush] or [done] for how to get any
   * errors generated by this call.
   */
  void writeln([Object? obj = ""]);

  /**
   * Writes the character of [charCode].
   *
   * This method is equivalent to `write(new String.fromCharCode(charCode))`.
   *
   * This operation is non-blocking. See [flush] or [done] for how to get any
   * errors generated by this call.
   */
  void writeCharCode(int charCode);

  /**
   * Passes the error to the target consumer as an error event.
   *
   * This function must not be called when a stream is currently being added
   * using [addStream].
   *
   * This operation is non-blocking. See [flush] or [done] for how to get any
   * errors generated by this call.
   */
  void addError(error, [StackTrace? stackTrace]);

  /**
   * Adds all elements of the given [stream] to `this`.
   *
   * Returns a [Future] that completes when
   * all elements of the given [stream] are added to `this`.
   *
   * This function must not be called when a stream is currently being added
   * using this function.
   */
  Future addStream(Stream<List<int>> stream);

  /**
   * Returns a [Future] that completes once all buffered data is accepted by the
   * underlying [StreamConsumer].
   *
   * This method must not be called while an [addStream] is incomplete.
   *
   * NOTE: This is not necessarily the same as the data being flushed by the
   * operating system.
   */
  Future flush();

  /**
   * Close the target consumer.
   *
   * NOTE: Writes to the [IOSink] may be buffered, and may not be flushed by
   * a call to `close()`. To flush all buffered writes, call `flush()` before
   * calling `close()`.
   */
  Future close();

  /**
   * Get a future that will complete when the consumer closes, or when an
   * error occurs. This future is identical to the future returned by
   * [close].
   */
  Future get done;
}

class _StreamSinkImpl<T> implements StreamSink<T> {
  final StreamConsumer<T> _target;
  final Completer _doneCompleter = new Completer();
  StreamController<T>? _controllerInstance;
  Completer? _controllerCompleter;
  bool _isClosed = false;
  bool _isBound = false;
  bool _hasError = false;

  _StreamSinkImpl(this._target);

  void add(T data) {
    if (_isClosed) {
      throw StateError("StreamSink is closed");
    }
    _controller.add(data);
  }

  void addError(error, [StackTrace? stackTrace]) {
    if (_isClosed) {
      throw StateError("StreamSink is closed");
    }
    _controller.addError(error, stackTrace);
  }

  Future addStream(Stream<T> stream) {
    if (_isBound) {
      throw new StateError("StreamSink is already bound to a stream");
    }
    if (_hasError) return done;

    _isBound = true;
    var future = _controllerCompleter == null
        ? _target.addStream(stream)
        : _controllerCompleter!.future.then((_) => _target.addStream(stream));
    _controllerInstance?.close();

    // Wait for any pending events in [_controller] to be dispatched before
    // adding [stream].
    return future.whenComplete(() {
      _isBound = false;
    });
  }

  Future flush() {
    if (_isBound) {
      throw new StateError("StreamSink is bound to a stream");
    }
    if (_controllerInstance == null) return new Future.value(this);
    // Adding an empty stream-controller will return a future that will complete
    // when all data is done.
    _isBound = true;
    var future = _controllerCompleter!.future;
    _controllerInstance!.close();
    return future.whenComplete(() {
      _isBound = false;
    });
  }

  Future close() {
    if (_isBound) {
      throw new StateError("StreamSink is bound to a stream");
    }
    if (!_isClosed) {
      _isClosed = true;
      if (_controllerInstance != null) {
        _controllerInstance!.close();
      } else {
        _closeTarget();
      }
    }
    return done;
  }

  void _closeTarget() {
    _target.close().then(_completeDoneValue, onError: _completeDoneError);
  }

  Future get done => _doneCompleter.future;

  void _completeDoneValue(value) {
    if (!_doneCompleter.isCompleted) {
      _doneCompleter.complete(value);
    }
  }

  void _completeDoneError(error, StackTrace? stackTrace) {
    if (!_doneCompleter.isCompleted) {
      _hasError = true;
      _doneCompleter.completeError(error, stackTrace);
    }
  }

  StreamController<T> get _controller {
    if (_isBound) {
      throw new StateError("StreamSink is bound to a stream");
    }
    if (_isClosed) {
      throw new StateError("StreamSink is closed");
    }
    if (_controllerInstance == null) {
      _controllerInstance = new StreamController<T>(sync: true);
      _controllerCompleter = new Completer();
      _target.addStream(_controller.stream).then((_) {
        if (_isBound) {
          // A new stream takes over - forward values to that stream.
          _controllerCompleter!.complete(this);
          _controllerCompleter = null;
          _controllerInstance = null;
        } else {
          // No new stream, .close was called. Close _target.
          _closeTarget();
        }
      }, onError: (error, stackTrace) {
        if (_isBound) {
          // A new stream takes over - forward errors to that stream.
          _controllerCompleter!.completeError(error, stackTrace);
          _controllerCompleter = null;
          _controllerInstance = null;
        } else {
          // No new stream. No need to close target, as it has already
          // failed.
          _completeDoneError(error, stackTrace);
        }
      });
    }
    return _controllerInstance!;
  }
}

class _IOSinkImpl extends _StreamSinkImpl<List<int>> implements IOSink {
  Encoding _encoding;
  bool _encodingMutable = true;

  _IOSinkImpl(StreamConsumer<List<int>> target, this._encoding) : super(target);

  Encoding get encoding => _encoding;

  void set encoding(Encoding value) {
    if (!_encodingMutable) {
      throw new StateError("IOSink encoding is not mutable");
    }
    _encoding = value;
  }

  void write(Object? obj) {
    String string = '$obj';
    if (string.isEmpty) return;
    add(_encoding.encode(string));
  }

  void writeAll(Iterable objects, [String separator = ""]) {
    Iterator iterator = objects.iterator;
    if (!iterator.moveNext()) return;
    if (separator.isEmpty) {
      do {
        write(iterator.current);
      } while (iterator.moveNext());
    } else {
      write(iterator.current);
      while (iterator.moveNext()) {
        write(separator);
        write(iterator.current);
      }
    }
  }

  void writeln([Object? object = ""]) {
    write(object);
    write("\n");
  }

  void writeCharCode(int charCode) {
    write(new String.fromCharCode(charCode));
  }
}
