package org.brotli.wrapper.enc;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.brotli.integration.BrotliJniTestBase;
import org.brotli.integration.BundleHelper;
import org.brotli.wrapper.common.BrotliCommon;
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.util.List;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.runner.RunWith;
import org.junit.runners.AllTests;

/** Tests for compression / decompression aided with LZ77 dictionary. */
@RunWith(AllTests.class)
public class UseCompoundDictionaryTest extends BrotliJniTestBase {

  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 UseCompoundDictionaryTestCase(entry));
      }
    } finally {
      bundle.close();
    }
    return suite;
  }

  /** Test case with a unique name. */
  static class UseCompoundDictionaryTestCase extends TestCase {
    final String entryName;
    UseCompoundDictionaryTestCase(String entryName) {
      super("UseCompoundDictionaryTest." + entryName);
      this.entryName = entryName;
    }

    @Override
    protected void runTest() throws Throwable {
      UseCompoundDictionaryTest.run(entryName);
    }
  }

  private static PreparedDictionary prepareDictionary(String entryName, ByteBuffer data) {
    if (entryName.endsWith("E.coli.txt")) {
      // Default prepared dictionary parameters doesn't work well for DNA data.
      // Should work well with 8-byte hash.
      return PreparedDictionaryGenerator.generate(data, 17, 3, 64, 5);
    } else {
       return Encoder.prepareDictionary(data);
    }
  }

  private static void run(String entryName) 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);
    }

    ByteBuffer dictionary = BrotliCommon.makeNative(original);
    PreparedDictionary preparedDictionary = prepareDictionary(entryName, dictionary);

    ByteArrayOutputStream dst = new ByteArrayOutputStream();
    BrotliOutputStream encoder =
        new BrotliOutputStream(dst, new Encoder.Parameters().setQuality(9).setWindow(23), 1 << 23);
    encoder.attachDictionary(preparedDictionary);
    try {
      encoder.write(original);
    } finally {
      encoder.close();
    }

    byte[] compressed = dst.toByteArray();

    // Just copy self from LZ77 dictionary -> ultimate compression ratio.
    assertTrue(compressed.length < 80 + original.length / 65536);

    BrotliInputStream decoder =
        new BrotliInputStream(new ByteArrayInputStream(compressed), 1 << 23);
    decoder.attachDictionary(dictionary);
    try {
      long originalCrc = BundleHelper.fingerprintStream(new ByteArrayInputStream(original));
      long crc = BundleHelper.fingerprintStream(decoder);
      assertEquals(originalCrc, crc);
    } finally {
      decoder.close();
    }
  }
}