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

/**
 * Private helper-class to handle native filters.
 */
abstract class _Filter {
  /**
   * Call to process a chunk of data. A call to [process] should only be made
   * when [processed] returns [null].
   */
  void process(List<int> data);

  /**
   * Get a chunk of processed data. When there are no more data available,
   * [processed] will return [null]. Set [flush] to [false] for non-final
   * calls to improve performance of some filters.
   *
   * The last call to [processed] should have [end] set to [true]. This will make
   * sure a 'end' packet is written on the stream.
   */
  List<int> processed({bool flush: true, bool end: false});

  /**
   * Mark the filter as closed. Always call this method for any filter created
   * to avoid leaking resources. [end] can be called at any time, but any
   * successive calls to [process] or [processed] will fail.
   */
  void end();

  external static _Filter newZLibDeflateFilter(bool gzip, int level);
  external static _Filter newZLibInflateFilter();
}


class _FilterTransformer extends StreamEventTransformer<List<int>, List<int>> {
  final _Filter _filter;
  bool _closed = false;
  bool _empty = true;

  _FilterTransformer(_Filter this._filter);

  void handleData(List<int> data, EventSink<List<int>> sink) {
    if (_closed) return;
    try {
      _empty = false;
      _filter.process(data);
      var out;
      while ((out = _filter.processed(flush: false)) != null) {
        sink.add(out);
      }
    } catch (e, s) {
      _closed = true;
      // TODO(floitsch): we are losing the stack trace.
      sink.addError(e);
      sink.close();
    }
  }

  void handleDone(EventSink<List<int>> sink) {
    if (_closed) return;
    if (_empty) _filter.process(const []);
    try {
      var out;
      while ((out = _filter.processed(end: true)) != null) {
        sink.add(out);
      }
    } catch (e, s) {
      // TODO(floitsch): we are losing the stack trace.
      sink.addError(e);
      _closed = true;
    }
    if (!_closed) _filter.end();
    _closed = true;
    sink.close();
  }
}


/**
 * ZLibDeflater class used to deflate a stream of bytes, using zlib.
 */
class ZLibDeflater extends _FilterTransformer {
  ZLibDeflater({bool gzip: true, int level: 6})
      : super(_Filter.newZLibDeflateFilter(gzip, level));
}


/**
 * ZLibInflater class used to inflate a stream of bytes, using zlib.
 */
class ZLibInflater extends _FilterTransformer {
  ZLibInflater() : super(_Filter.newZLibInflateFilter());
}

