/* 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.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
   */
  public BrotliOutputStream(OutputStream destination, Encoder.Parameters params, int bufferSize)
      throws IOException {
    this.encoder = new Encoder(Channels.newChannel(destination), params, bufferSize);
  }

  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());
  }

  public void attachDictionary(PreparedDictionary dictionary) throws IOException {
    encoder.attachDictionary(dictionary);
  }

  @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;
    }
  }
}
