package org.brotli.wrapper.enc;

import static org.junit.Assert.assertEquals;

import org.brotli.integration.BundleHelper;
import org.brotli.wrapper.dec.BrotliInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import java.util.List;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.runner.RunWith;
import org.junit.runners.AllTests;

/** Tests for {@link org.brotli.wrapper.enc.BrotliEncoderChannel}. */
@RunWith(AllTests.class)
public class BrotliEncoderChannelTest {

  private enum TestMode {
    WRITE_ALL,
    WRITE_CHUNKS
  }

  // TODO: remove when Bazel get JNI support.
  static {
    System.load(new java.io.File(new java.io.File(System.getProperty("java.library.path")),
        "liblibjni.so").getAbsolutePath());
  }

  private static final int CHUNK_SIZE = 256;

  static InputStream getBundle() throws IOException {
    return new FileInputStream(System.getProperty("TEST_BUNDLE"));
  }

  /** Creates a test suite. */
  public static TestSuite suite() throws IOException {
    TestSuite suite = new TestSuite();
    InputStream bundle = getBundle();
    try {
      List<String> entries = BundleHelper.listEntries(bundle);
      for (String entry : entries) {
        suite.addTest(new ChannleTestCase(entry, TestMode.WRITE_ALL));
        suite.addTest(new ChannleTestCase(entry, TestMode.WRITE_CHUNKS));
      }
    } finally {
      bundle.close();
    }
    return suite;
  }

  /** Test case with a unique name. */
  static class ChannleTestCase extends TestCase {
    final String entryName;
    final TestMode mode;
    ChannleTestCase(String entryName, TestMode mode) {
      super("BrotliEncoderChannelTest." + entryName + "." + mode.name());
      this.entryName = entryName;
      this.mode = mode;
    }

    @Override
    protected void runTest() throws Throwable {
      BrotliEncoderChannelTest.run(entryName, mode);
    }
  }

  private static void run(String entryName, TestMode mode) throws Throwable {
    InputStream bundle = getBundle();
    byte[] original;
    try {
      original = BundleHelper.readEntry(bundle, entryName);
    } finally {
      bundle.close();
    }
    if (original == null) {
      throw new RuntimeException("Can't read bundle entry: " + entryName);
    }

    if ((mode == TestMode.WRITE_CHUNKS) && (original.length <= CHUNK_SIZE)) {
      return;
    }

    ByteArrayOutputStream dst = new ByteArrayOutputStream();
    WritableByteChannel encoder = new BrotliEncoderChannel(Channels.newChannel(dst));
    ByteBuffer src = ByteBuffer.wrap(original);
    try {
      switch (mode) {
        case WRITE_ALL:
          encoder.write(src);
          break;

        case WRITE_CHUNKS:
          while (src.hasRemaining()) {
            int limit = Math.min(CHUNK_SIZE, src.remaining());
            ByteBuffer slice = src.slice();
            slice.limit(limit);
            src.position(src.position() + limit);
            encoder.write(slice);
          }
          break;
      }
    } finally {
      encoder.close();
    }

    InputStream decoder = new BrotliInputStream(new ByteArrayInputStream(dst.toByteArray()));
    try {
      long originalCrc = BundleHelper.fingerprintStream(new ByteArrayInputStream(original));
      long crc = BundleHelper.fingerprintStream(decoder);
      assertEquals(originalCrc, crc);
    } finally {
      decoder.close();
    }
  }
}
