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

// @dart = 2.6

part of dart.io;

/**
 * Exposes ZLib options for input parameters.
 *
 * See http://www.zlib.net/manual.html for more documentation.
 */
abstract class ZLibOption {
  /// Minimal value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits]
  /// and [ZLibDecoder.windowBits].
  static const int minWindowBits = 8;
  @Deprecated("Use minWindowBits instead")
  static const int MIN_WINDOW_BITS = 8;

  /// Maximal value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits]
  /// and [ZLibDecoder.windowBits].
  static const int maxWindowBits = 15;
  @Deprecated("Use maxWindowBits instead")
  static const int MAX_WINDOW_BITS = 15;

  /// Default value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits]
  /// and [ZLibDecoder.windowBits].
  static const int defaultWindowBits = 15;
  @Deprecated("Use defaultWindowBits instead")
  static const int DEFAULT_WINDOW_BITS = 15;

  /// Minimal value for [ZLibCodec.level] and [ZLibEncoder.level].
  static const int minLevel = -1;
  @Deprecated("Use minLevel instead")
  static const int MIN_LEVEL = -1;

  /// Maximal value for [ZLibCodec.level] and [ZLibEncoder.level]
  static const int maxLevel = 9;
  @Deprecated("Use maxLevel instead")
  static const int MAX_LEVEL = 9;

  /// Default value for [ZLibCodec.level] and [ZLibEncoder.level].
  static const int defaultLevel = 6;
  @Deprecated("Use defaultLevel instead")
  static const int DEFAULT_LEVEL = 6;

  /// Minimal value for [ZLibCodec.memLevel] and [ZLibEncoder.memLevel].
  static const int minMemLevel = 1;
  @Deprecated("Use minMemLevel instead")
  static const int MIN_MEM_LEVEL = 1;

  /// Maximal value for [ZLibCodec.memLevel] and [ZLibEncoder.memLevel].
  static const int maxMemLevel = 9;
  @Deprecated("Use maxMemLevel instead")
  static const int MAX_MEM_LEVEL = 9;

  /// Default value for [ZLibCodec.memLevel] and [ZLibEncoder.memLevel].
  static const int defaultMemLevel = 8;
  @Deprecated("Use defaultMemLevel instead")
  static const int DEFAULT_MEM_LEVEL = 8;

  /// Recommended strategy for data produced by a filter (or predictor)
  static const int strategyFiltered = 1;
  @Deprecated("Use strategyFiltered instead")
  static const int STRATEGY_FILTERED = 1;

  /// Use this strategy to force Huffman encoding only (no string match)
  static const int strategyHuffmanOnly = 2;
  @Deprecated("Use strategyHuffmanOnly instead")
  static const int STRATEGY_HUFFMAN_ONLY = 2;

  /// Use this strategy to limit match distances to one (run-length encoding)
  static const int strategyRle = 3;
  @Deprecated("Use strategyRle instead")
  static const int STRATEGY_RLE = 3;

  /// This strategy prevents the use of dynamic Huffman codes, allowing for a
  /// simpler decoder
  static const int strategyFixed = 4;
  @Deprecated("Use strategyFixed instead")
  static const int STRATEGY_FIXED = 4;

  /// Recommended strategy for normal data
  static const int strategyDefault = 0;
  @Deprecated("Use strategyDefault instead")
  static const int STRATEGY_DEFAULT = 0;
}

/**
 * An instance of the default implementation of the [ZLibCodec].
 */
const ZLibCodec zlib = const ZLibCodec._default();
@Deprecated("Use zlib instead")
const ZLibCodec ZLIB = zlib;

/**
 * The [ZLibCodec] encodes raw bytes to ZLib compressed bytes and decodes ZLib
 * compressed bytes to raw bytes.
 */
class ZLibCodec extends Codec<List<int>, List<int>> {
  /**
   * When true, `GZip` frames will be added to the compressed data.
   */
  final bool gzip;

  /**
   * The compression-[level] can be set in the range of `-1..9`, with `6` being
   * the default compression level. Levels above `6` will have higher
   * compression rates at the cost of more CPU and memory usage. Levels below
   * `6` will use less CPU and memory at the cost of lower compression rates.
   */
  final int level;

  /**
   * Specifies how much memory should be allocated for the internal compression
   * state. `1` uses minimum memory but is slow and reduces compression ratio;
   * `9` uses maximum memory for optimal speed. The default value is `8`.
   *
   * The memory requirements for deflate are (in bytes):
   *
   *     (1 << (windowBits + 2)) +  (1 << (memLevel + 9))
   * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values)
   */
  final int memLevel;

  /**
   * Tunes the compression algorithm. Use the value strategyDefault for normal
   * data, strategyFiltered for data produced by a filter (or predictor),
   * strategyHuffmanOnly to force Huffman encoding only (no string match), or
   * strategyRle to limit match distances to one (run-length encoding).
   */
  final int strategy;

  /**
   * Base two logarithm of the window size (the size of the history buffer). It
   * should be in the range 8..15. Larger values result in better compression at
   * the expense of memory usage. The default value is 15
   */
  final int windowBits;

  /**
   * When true, deflate generates raw data with no zlib header or trailer, and
   * will not compute an adler32 check value
   */
  final bool raw;

  /**
   * Initial compression dictionary.
   *
   * It should consist of strings (byte sequences) that are likely to be
   * encountered later in the data to be compressed, with the most commonly used
   * strings preferably put towards the end of the dictionary. Using a
   * dictionary is most useful when the data to be compressed is short and can
   * be predicted with good accuracy; the data can then be compressed better
   * than with the default empty dictionary.
   */
  final List<int> dictionary;

  ZLibCodec(
      {this.level: ZLibOption.defaultLevel,
      this.windowBits: ZLibOption.defaultWindowBits,
      this.memLevel: ZLibOption.defaultMemLevel,
      this.strategy: ZLibOption.strategyDefault,
      this.dictionary,
      this.raw: false,
      this.gzip: false}) {
    _validateZLibeLevel(level);
    _validateZLibMemLevel(memLevel);
    _validateZLibStrategy(strategy);
    _validateZLibWindowBits(windowBits);
  }

  const ZLibCodec._default()
      : level = ZLibOption.defaultLevel,
        windowBits = ZLibOption.defaultWindowBits,
        memLevel = ZLibOption.defaultMemLevel,
        strategy = ZLibOption.strategyDefault,
        raw = false,
        gzip = false,
        dictionary = null;

  /**
   * Get a [ZLibEncoder] for encoding to `ZLib` compressed data.
   */
  ZLibEncoder get encoder => new ZLibEncoder(
      gzip: false,
      level: level,
      windowBits: windowBits,
      memLevel: memLevel,
      strategy: strategy,
      dictionary: dictionary,
      raw: raw);

  /**
   * Get a [ZLibDecoder] for decoding `ZLib` compressed data.
   */
  ZLibDecoder get decoder =>
      new ZLibDecoder(windowBits: windowBits, dictionary: dictionary, raw: raw);
}

/**
 * An instance of the default implementation of the [GZipCodec].
 */
const GZipCodec gzip = const GZipCodec._default();
@Deprecated("Use gzip instead")
const GZipCodec GZIP = gzip;

/**
 * The [GZipCodec] encodes raw bytes to GZip compressed bytes and decodes GZip
 * compressed bytes to raw bytes.
 *
 * The difference between [ZLibCodec] and [GZipCodec] is that the [GZipCodec]
 * wraps the `ZLib` compressed bytes in `GZip` frames.
 */
class GZipCodec extends Codec<List<int>, List<int>> {
  /**
   * When true, `GZip` frames will be added to the compressed data.
   */
  final bool gzip;

  /**
   * The compression-[level] can be set in the range of `-1..9`, with `6` being
   * the default compression level. Levels above `6` will have higher
   * compression rates at the cost of more CPU and memory usage. Levels below
   * `6` will use less CPU and memory at the cost of lower compression rates.
   */
  final int level;

  /**
   * Specifies how much memory should be allocated for the internal compression
   * state. `1` uses minimum memory but is slow and reduces compression ratio;
   * `9` uses maximum memory for optimal speed. The default value is `8`.
   *
   * The memory requirements for deflate are (in bytes):
   *
   *     (1 << (windowBits + 2)) +  (1 << (memLevel + 9))
   * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values)
   */
  final int memLevel;

  /**
   * Tunes the compression algorithm. Use the value
   * [ZLibOption.strategyDefault] for normal data,
   * [ZLibOption.strategyFiltered] for data produced by a filter
   * (or predictor), [ZLibOption.strategyHuffmanOnly] to force Huffman
   * encoding only (no string match), or [ZLibOption.strategyRle] to limit
   * match distances to one (run-length encoding).
   */
  final int strategy;

  /**
   * Base two logarithm of the window size (the size of the history buffer). It
   * should be in the range `8..15`. Larger values result in better compression
   * at the expense of memory usage. The default value is `15`
   */
  final int windowBits;

  /**
   * Initial compression dictionary.
   *
   * It should consist of strings (byte sequences) that are likely to be
   * encountered later in the data to be compressed, with the most commonly used
   * strings preferably put towards the end of the dictionary. Using a
   * dictionary is most useful when the data to be compressed is short and can
   * be predicted with good accuracy; the data can then be compressed better
   * than with the default empty dictionary.
   */
  final List<int> dictionary;

  /**
   * When true, deflate generates raw data with no zlib header or trailer, and
   * will not compute an adler32 check value
   */
  final bool raw;

  GZipCodec(
      {this.level: ZLibOption.defaultLevel,
      this.windowBits: ZLibOption.defaultWindowBits,
      this.memLevel: ZLibOption.defaultMemLevel,
      this.strategy: ZLibOption.strategyDefault,
      this.dictionary,
      this.raw: false,
      this.gzip: true}) {
    _validateZLibeLevel(level);
    _validateZLibMemLevel(memLevel);
    _validateZLibStrategy(strategy);
    _validateZLibWindowBits(windowBits);
  }

  const GZipCodec._default()
      : level = ZLibOption.defaultLevel,
        windowBits = ZLibOption.defaultWindowBits,
        memLevel = ZLibOption.defaultMemLevel,
        strategy = ZLibOption.strategyDefault,
        raw = false,
        gzip = true,
        dictionary = null;

  /**
   * Get a [ZLibEncoder] for encoding to `GZip` compressed data.
   */
  ZLibEncoder get encoder => new ZLibEncoder(
      gzip: true,
      level: level,
      windowBits: windowBits,
      memLevel: memLevel,
      strategy: strategy,
      dictionary: dictionary,
      raw: raw);

  /**
   * Get a [ZLibDecoder] for decoding `GZip` compressed data.
   */
  ZLibDecoder get decoder =>
      new ZLibDecoder(windowBits: windowBits, dictionary: dictionary, raw: raw);
}

/**
 * The [ZLibEncoder] encoder is used by [ZLibCodec] and [GZipCodec] to compress
 * data.
 */
class ZLibEncoder extends Converter<List<int>, List<int>> {
  /**
   * When true, `GZip` frames will be added to the compressed data.
   */
  final bool gzip;

  /**
   * The compression-[level] can be set in the range of `-1..9`, with `6` being
   * the default compression level. Levels above `6` will have higher
   * compression rates at the cost of more CPU and memory usage. Levels below
   * `6` will use less CPU and memory at the cost of lower compression rates.
   */
  final int level;

  /**
   * Specifies how much memory should be allocated for the internal compression
   * state. `1` uses minimum memory but is slow and reduces compression ratio;
   * `9` uses maximum memory for optimal speed. The default value is `8`.
   *
   * The memory requirements for deflate are (in bytes):
   *
   *     (1 << (windowBits + 2)) +  (1 << (memLevel + 9))
   * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values)
   */
  final int memLevel;

  /**
   * Tunes the compression algorithm. Use the value
   * [ZLibOption.strategyDefault] for normal data,
   * [ZLibOption.strategyFiltered] for data produced by a filter
   * (or predictor), [ZLibOption.strategyHuffmanOnly] to force Huffman
   * encoding only (no string match), or [ZLibOption.strategyRle] to limit
   * match distances to one (run-length encoding).
   */
  final int strategy;

  /**
   * Base two logarithm of the window size (the size of the history buffer). It
   * should be in the range `8..15`. Larger values result in better compression
   * at the expense of memory usage. The default value is `15`
   */
  final int windowBits;

  /**
   * Initial compression dictionary.
   *
   * It should consist of strings (byte sequences) that are likely to be
   * encountered later in the data to be compressed, with the most commonly used
   * strings preferably put towards the end of the dictionary. Using a
   * dictionary is most useful when the data to be compressed is short and can
   * be predicted with good accuracy; the data can then be compressed better
   * than with the default empty dictionary.
   */
  final List<int> dictionary;

  /**
   * When true, deflate generates raw data with no zlib header or trailer, and
   * will not compute an adler32 check value
   */
  final bool raw;

  ZLibEncoder(
      {this.gzip: false,
      this.level: ZLibOption.defaultLevel,
      this.windowBits: ZLibOption.defaultWindowBits,
      this.memLevel: ZLibOption.defaultMemLevel,
      this.strategy: ZLibOption.strategyDefault,
      this.dictionary,
      this.raw: false}) {
    _validateZLibeLevel(level);
    _validateZLibMemLevel(memLevel);
    _validateZLibStrategy(strategy);
    _validateZLibWindowBits(windowBits);
  }

  /**
   * Convert a list of bytes using the options given to the ZLibEncoder
   * constructor.
   */
  List<int> convert(List<int> bytes) {
    _BufferSink sink = new _BufferSink();
    startChunkedConversion(sink)
      ..add(bytes)
      ..close();
    return sink.builder.takeBytes();
  }

  /**
   * Start a chunked conversion using the options given to the [ZLibEncoder]
   * constructor. While it accepts any [Sink] taking [List<int>]'s,
   * the optimal sink to be passed as [sink] is a [ByteConversionSink].
   */
  ByteConversionSink startChunkedConversion(Sink<List<int>> sink) {
    if (sink is! ByteConversionSink) {
      sink = new ByteConversionSink.from(sink);
    }
    return new _ZLibEncoderSink._(
        sink, gzip, level, windowBits, memLevel, strategy, dictionary, raw);
  }
}

/**
 * The [ZLibDecoder] is used by [ZLibCodec] and [GZipCodec] to decompress data.
 */
class ZLibDecoder extends Converter<List<int>, List<int>> {
  /**
   * Base two logarithm of the window size (the size of the history buffer). It
   * should be in the range `8..15`. Larger values result in better compression
   * at the expense of memory usage. The default value is `15`.
   */
  final int windowBits;

  /**
   * Initial compression dictionary.
   *
   * It should consist of strings (byte sequences) that are likely to be
   * encountered later in the data to be compressed, with the most commonly used
   * strings preferably put towards the end of the dictionary. Using a
   * dictionary is most useful when the data to be compressed is short and can
   * be predicted with good accuracy; the data can then be compressed better
   * than with the default empty dictionary.
   */
  final List<int> dictionary;

  /**
   * When true, deflate generates raw data with no zlib header or trailer, and
   * will not compute an adler32 check value
   */
  final bool raw;

  ZLibDecoder(
      {this.windowBits: ZLibOption.defaultWindowBits,
      this.dictionary,
      this.raw: false}) {
    _validateZLibWindowBits(windowBits);
  }

  /**
   * Convert a list of bytes using the options given to the [ZLibDecoder]
   * constructor.
   */
  List<int> convert(List<int> bytes) {
    _BufferSink sink = new _BufferSink();
    startChunkedConversion(sink)
      ..add(bytes)
      ..close();
    return sink.builder.takeBytes();
  }

  /**
   * Start a chunked conversion. While it accepts any [Sink]
   * taking [List<int>]'s, the optimal sink to be passed as [sink] is a
   * [ByteConversionSink].
   */
  ByteConversionSink startChunkedConversion(Sink<List<int>> sink) {
    if (sink is! ByteConversionSink) {
      sink = new ByteConversionSink.from(sink);
    }
    return new _ZLibDecoderSink._(sink, windowBits, dictionary, raw);
  }
}

/**
 * The [RawZLibFilter] class provides a low-level interface to zlib.
 */
abstract class RawZLibFilter {
  /**
   * Returns a a [RawZLibFilter] whose [process] and [processed] methods
   * compress data.
   */
  factory RawZLibFilter.deflateFilter({
    bool gzip: false,
    int level: ZLibOption.defaultLevel,
    int windowBits: ZLibOption.defaultWindowBits,
    int memLevel: ZLibOption.defaultMemLevel,
    int strategy: ZLibOption.strategyDefault,
    List<int> dictionary,
    bool raw: false,
  }) {
    return _makeZLibDeflateFilter(
        gzip, level, windowBits, memLevel, strategy, dictionary, raw);
  }

  /**
   * Returns a a [RawZLibFilter] whose [process] and [processed] methods
   * decompress data.
   */
  factory RawZLibFilter.inflateFilter({
    int windowBits: ZLibOption.defaultWindowBits,
    List<int> dictionary,
    bool raw: false,
  }) {
    return _makeZLibInflateFilter(windowBits, dictionary, raw);
  }

  /**
   * Call to process a chunk of data. A call to [process] should only be made
   * when [processed] returns [:null:].
   */
  void process(List<int> data, int start, int end);

  /**
   * 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 an 'end' packet is written on the stream.
   */
  List<int> processed({bool flush: true, bool end: false});

  external static RawZLibFilter _makeZLibDeflateFilter(
      bool gzip,
      int level,
      int windowBits,
      int memLevel,
      int strategy,
      List<int> dictionary,
      bool raw);

  external static RawZLibFilter _makeZLibInflateFilter(
      int windowBits, List<int> dictionary, bool raw);
}

class _BufferSink extends ByteConversionSink {
  final BytesBuilder builder = new BytesBuilder(copy: false);

  void add(List<int> chunk) {
    builder.add(chunk);
  }

  void addSlice(List<int> chunk, int start, int end, bool isLast) {
    if (chunk is Uint8List) {
      Uint8List list = chunk;
      builder.add(new Uint8List.view(
          list.buffer, list.offsetInBytes + start, end - start));
    } else {
      builder.add(chunk.sublist(start, end));
    }
  }

  void close() {}
}

class _ZLibEncoderSink extends _FilterSink {
  _ZLibEncoderSink._(
      ByteConversionSink sink,
      bool gzip,
      int level,
      int windowBits,
      int memLevel,
      int strategy,
      List<int> dictionary,
      bool raw)
      : super(
            sink,
            RawZLibFilter._makeZLibDeflateFilter(
                gzip, level, windowBits, memLevel, strategy, dictionary, raw));
}

class _ZLibDecoderSink extends _FilterSink {
  _ZLibDecoderSink._(
      ByteConversionSink sink, int windowBits, List<int> dictionary, bool raw)
      : super(sink,
            RawZLibFilter._makeZLibInflateFilter(windowBits, dictionary, raw));
}

class _FilterSink extends ByteConversionSink {
  final RawZLibFilter _filter;
  final ByteConversionSink _sink;
  bool _closed = false;
  bool _empty = true;

  _FilterSink(this._sink, this._filter);

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

  void addSlice(List<int> data, int start, int end, bool isLast) {
    if (_closed) return;
    if (end == null) throw new ArgumentError.notNull("end");
    RangeError.checkValidRange(start, end, data.length);
    try {
      _empty = false;
      _BufferAndStart bufferAndStart =
          _ensureFastAndSerializableByteData(data, start, end);
      _filter.process(bufferAndStart.buffer, bufferAndStart.start,
          end - (start - bufferAndStart.start));
      List<int> out;
      while ((out = _filter.processed(flush: false)) != null) {
        _sink.add(out);
      }
    } catch (e) {
      _closed = true;
      rethrow;
    }

    if (isLast) close();
  }

  void close() {
    if (_closed) return;
    // Be sure to send process an empty chunk of data. Without this, the empty
    // message would not have a GZip frame (if compressed with GZip).
    if (_empty) _filter.process(const [], 0, 0);
    try {
      List<int> out;
      while ((out = _filter.processed(end: true)) != null) {
        _sink.add(out);
      }
    } catch (e) {
      // TODO(kevmoo): not sure why this isn't a try/finally
      _closed = true;
      throw e;
    }
    _closed = true;
    _sink.close();
  }
}

void _validateZLibWindowBits(int windowBits) {
  if (ZLibOption.minWindowBits > windowBits ||
      ZLibOption.maxWindowBits < windowBits) {
    throw new RangeError.range(
        windowBits, ZLibOption.minWindowBits, ZLibOption.maxWindowBits);
  }
}

void _validateZLibeLevel(int level) {
  if (ZLibOption.minLevel > level || ZLibOption.maxLevel < level) {
    throw new RangeError.range(level, ZLibOption.minLevel, ZLibOption.maxLevel);
  }
}

void _validateZLibMemLevel(int memLevel) {
  if (ZLibOption.minMemLevel > memLevel || ZLibOption.maxMemLevel < memLevel) {
    throw new RangeError.range(
        memLevel, ZLibOption.minMemLevel, ZLibOption.maxMemLevel);
  }
}

void _validateZLibStrategy(int strategy) {
  const strategies = const <int>[
    ZLibOption.strategyFiltered,
    ZLibOption.strategyHuffmanOnly,
    ZLibOption.strategyRle,
    ZLibOption.strategyFixed,
    ZLibOption.strategyDefault
  ];
  if (strategies.indexOf(strategy) == -1) {
    throw new ArgumentError("Unsupported 'strategy'");
  }
}
