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

/**
 * This class provides an interface for converters to
 * efficiently transmit String data.
 *
 * Instead of limiting the interface to one non-chunked String it accepts
 * partial strings or can be transformed into a byte sink that
 * accepts UTF-8 code units.
 */
abstract class StringConversionSink
    extends ChunkedConversionSink<String> {
  StringConversionSink();
  factory StringConversionSink.withCallback(void callback(String accumulated))
      = _StringCallbackSink;
  factory StringConversionSink.from(ChunkedConversionSink<String> sink)
      = _StringAdapterSink;

  /**
   * Creates a new instance wrapping the given [sink].
   *
   * Every string that is added to the returned instance is forwarded to
   * the [sink]. The instance is allowed to buffer and is not required to
   * forward immediately.
   */
  factory StringConversionSink.fromStringSink(StringSink sink) =
      _StringSinkConversionSink;

  /**
   * Adds the next [chunk] to `this`.
   *
   * Adds the substring defined by [start] and [end]-exclusive to `this`.
   *
   * If [isLast] is `true` closes `this`.
   */
  void addSlice(String chunk, int start, int end, bool isLast);

  /**
   * Returns `this` as a sink that accepts UTF-8 input.
   *
   * If used, this method must be the first and only call to `this`. It
   * invalidates `this`. All further operations must be performed on the result.
   */
  ByteConversionSink asUtf8Sink(bool allowMalformed);
  // - asRuneSink
  // - asCodeUnitsSink

  /**
   * Returns `this` as a [ClosableStringSink].
   *
   * If used, this method must be the first and only call to `this`. It
   * invalidates `this`. All further operations must be performed on the result.
   */
  ClosableStringSink asStringSink();
}

/**
 * A [ClosableStringSink] extends the [StringSink] interface by adding a
 * `close` method.
 */
abstract class ClosableStringSink extends StringSink {
  /**
   * Creates a new instance combining a [StringSink] [sink] and a callback
   * [onClose] which is invoked when the returned instance is closed.
   */
  factory ClosableStringSink.fromStringSink(StringSink sink, void onClose())
      = _ClosableStringSink;

  /**
   * Closes `this` and flushes any outstanding data.
   */
  void close();
}

typedef void _StringSinkCloseCallback();

/**
 * This class wraps an existing [StringSink] and invokes a
 * closure when [close] is invoked.
 */
class _ClosableStringSink implements ClosableStringSink {
  final _StringSinkCloseCallback _callback;
  final StringSink _sink;

  _ClosableStringSink(this._sink, this._callback);

  void close() => _callback();

  void writeCharCode(int charCode) => _sink.writeCharCode(charCode);
  void write(Object o) => _sink.write(o);
  void writeln([Object o]) => _sink.writeln(o);
  void writeAll(Iterable objects, [String separator])
      => _sink.writeAll(objects, separator);
}

/**
 * This class wraps an existing [StringConversionSink] and exposes a
 * [ClosableStringSink] interface. The wrapped sink only needs to implement
 * `add` and `close`.
 */
// TODO(floitsch): make this class public?
class _StringConversionSinkAsStringSinkAdapter implements ClosableStringSink {
  static const _MIN_STRING_SIZE = 16;

  StringBuffer _buffer;
  StringConversionSink _chunkedSink;

  _StringConversionSinkAsStringSinkAdapter(this._chunkedSink)
      : _buffer = new StringBuffer();

  void close() {
    if (_buffer.isNotEmpty) _flush();
    _chunkedSink.close();
  }

  void writeCharCode(int charCode) {
    _buffer.writeCharCode(charCode);
    if (_buffer.length > _MIN_STRING_SIZE) _flush();
  }

  void write(Object o) {
    if (_buffer.isNotEmpty) _flush();
    String str = o.toString();
    _chunkedSink.add(o.toString());
  }

  void writeln([Object o]) {
    _buffer.writeln(o);
    if (_buffer.length > _MIN_STRING_SIZE) _flush();
  }

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

  void _flush() {
    String accumulated = _buffer.toString();
    _buffer.clear();
    _chunkedSink.add(accumulated);
  }
}

/**
 * This class provides a base-class for converters that need to accept String
 * inputs.
 */
abstract class StringConversionSinkBase extends StringConversionSinkMixin {
}

/**
 * This class provides a mixin for converters that need to accept String
 * inputs.
 */
abstract class StringConversionSinkMixin implements StringConversionSink {

  void addSlice(String str, int start, int end, bool isLast);
  void close();

  void add(String str) => addSlice(str, 0, str.length, false);

  ByteConversionSink asUtf8Sink(bool allowMalformed) {
    return new _Utf8ConversionSink(this, allowMalformed);
  }

  ClosableStringSink asStringSink() {
    return new _StringConversionSinkAsStringSinkAdapter(this);
  }
}

/**
 * This class is a [StringConversionSink] that wraps a [StringSink].
 */
class _StringSinkConversionSink extends StringConversionSinkBase {
  StringSink _stringSink;
  _StringSinkConversionSink(StringSink this._stringSink);

  void close() {}
  void addSlice(String str, int start, int end, bool isLast) {
    if (start != 0 || end != str.length) {
      for (int i = start; i < end; i++) {
        _stringSink.writeCharCode(str.codeUnitAt(i));
      }
    } else {
      _stringSink.write(str);
    }
    if (isLast) close();
  }

  void add(String str) => _stringSink.write(str);

  ByteConversionSink asUtf8Sink(bool allowMalformed) {
    return new _Utf8StringSinkAdapter(this, _stringSink, allowMalformed);
  }

  ClosableStringSink asStringSink() {
    return new ClosableStringSink.fromStringSink(_stringSink, this.close);
  }
}

/**
 * This class accumulates all chunks into one string
 * and invokes a callback when the sink is closed.
 *
 * This class can be used to terminate a chunked conversion.
 */
class _StringCallbackSink extends _StringSinkConversionSink {
  final _ChunkedConversionCallback<String> _callback;
  _StringCallbackSink(this._callback) : super(new StringBuffer());

  void close() {
    StringBuffer buffer = _stringSink;
    String accumulated = buffer.toString();
    buffer.clear();
    _callback(accumulated);
  }

  ByteConversionSink asUtf8Sink(bool allowMalformed) {
    return new _Utf8StringSinkAdapter(
        this, _stringSink, allowMalformed);
  }
}

/**
 * This class adapts a simple [ChunkedConversionSink] to a
 * [StringConversionSink].
 *
 * All additional methods of the [StringConversionSink] (compared to the
 * ChunkedConversionSink) are redirected to the `add` method.
 */
class _StringAdapterSink extends StringConversionSinkBase {
  final ChunkedConversionSink<String> _sink;

  _StringAdapterSink(this._sink);

  void add(String str) => _sink.add(str);

  void addSlice(String str, int start, int end, bool isLast) {
    if (start == 0 && end == str.length) {
      add(str);
    } else {
      add(str.substring(start, end));
    }
    if (isLast) close();
  }

  void close() => _sink.close();
}


/**
 * Decodes UTF-8 code units and stores them in a [StringSink].
 */
class _Utf8StringSinkAdapter extends ByteConversionSink {
  final _Utf8Decoder _decoder;
  final ChunkedConversionSink _chunkedSink;

  _Utf8StringSinkAdapter(ChunkedConversionSink chunkedSink,
                         StringSink sink, bool allowMalformed)
      : _chunkedSink = chunkedSink,
        _decoder = new _Utf8Decoder(sink, allowMalformed);

  void close() {
    _decoder.close();
    if(_chunkedSink != null) _chunkedSink.close();
  }

  void add(List<int> chunk) {
    addSlice(chunk, 0, chunk.length, false);
  }

  void addSlice(List<int> codeUnits, int startIndex, int endIndex,
                bool isLast) {
    _decoder.convert(codeUnits, startIndex, endIndex);
    if (isLast) close();
  }
}

/**
 * Decodes UTF-8 code units.
 *
 * Forwards the decoded strings to the given [StringConversionSink].
 */
// TODO(floitsch): make this class public?
class _Utf8ConversionSink extends ByteConversionSink {
  static const _MIN_STRING_SIZE = 16;

  final _Utf8Decoder _decoder;
  final StringConversionSink _chunkedSink;
  final StringBuffer _buffer;
  _Utf8ConversionSink(StringConversionSink sink, bool allowMalformed)
      : this._(sink, new StringBuffer(), allowMalformed);

  _Utf8ConversionSink._(this._chunkedSink, StringBuffer stringBuffer,
                       bool allowMalformed)
      : _decoder = new _Utf8Decoder(stringBuffer, allowMalformed),
        _buffer = stringBuffer;

  void close() {
    _decoder.close();
    if (_buffer.isNotEmpty) {
      String accumulated = _buffer.toString();
      _buffer.clear();
      _chunkedSink.addSlice(accumulated, 0, accumulated.length, true);
    } else  {
      _chunkedSink.close();
    }
  }

  void add(List<int> chunk) {
    addSlice(chunk, 0, chunk.length, false);
  }

  void addSlice(List<int> chunk, int startIndex, int endIndex,
                bool isLast) {
    _decoder.convert(chunk, startIndex, endIndex);
    if (_buffer.length > _MIN_STRING_SIZE) {
      String accumulated = _buffer.toString();
      _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast);
      _buffer.clear();
      return;
    }
    if (isLast) close();
  }
}
