/* Copyright 2017 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

package org.brotli.wrapper.enc;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;

/**
 * Output stream that wraps native brotli encoder.
 */
public class BrotliOutputStream extends OutputStream {
  /** The default internal buffer size used by the encoder. */
  private static final int DEFAULT_BUFFER_SIZE = 16384;

  private final Encoder encoder;

  /**
   * Creates a BrotliOutputStream.
   *
   * @param destination underlying destination
   * @param params encoding settings
   * @param bufferSize intermediate buffer size
   * @param customDictionary initial LZ77 dictionary
   */
  public BrotliOutputStream(OutputStream destination, Encoder.Parameters params, int bufferSize,
      ByteBuffer customDictionary) throws IOException {
    this.encoder = new Encoder(
        Channels.newChannel(destination), params, bufferSize, customDictionary);
  }

  public BrotliOutputStream(OutputStream destination, Encoder.Parameters params, int bufferSize)
      throws IOException {
    this.encoder = new Encoder(Channels.newChannel(destination), params, bufferSize, null);
  }

  public BrotliOutputStream(OutputStream destination, Encoder.Parameters params)
      throws IOException {
    this(destination, params, DEFAULT_BUFFER_SIZE);
  }

  public BrotliOutputStream(OutputStream destination) throws IOException {
    this(destination, new Encoder.Parameters());
  }

  @Override
  public void close() throws IOException {
    encoder.close();
  }

  @Override
  public void flush() throws IOException {
    if (encoder.closed) {
      throw new IOException("write after close");
    }
    encoder.flush();
  }

  @Override
  public void write(int b) throws IOException {
    if (encoder.closed) {
      throw new IOException("write after close");
    }
    while (!encoder.encode(EncoderJNI.Operation.PROCESS)) {
      // Busy-wait loop.
    }
    encoder.inputBuffer.put((byte) b);
  }

  @Override
  public void write(byte[] b) throws IOException {
    this.write(b, 0, b.length);
  }

  @Override
  public void write(byte[] b, int off, int len) throws IOException {
    if (encoder.closed) {
      throw new IOException("write after close");
    }
    while (len > 0) {
      if (!encoder.encode(EncoderJNI.Operation.PROCESS)) {
        continue;
      }
      int limit = Math.min(len, encoder.inputBuffer.remaining());
      encoder.inputBuffer.put(b, off, limit);
      off += limit;
      len -= limit;
    }
  }
}
