package org.aomedia.avif.android;

import static com.google.common.truth.Truth.assertThat;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import androidx.test.platform.app.InstrumentationRegistry;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

/** Instrumentation tests for the libavif JNI API, which will execute on an Android device. */
@RunWith(Parameterized.class)
public class AnimatedImageTest {

  private static final int AVIF_RESULT_OK = 0;

  private static class Image {
    public final String filename;
    public final int width;
    public final int height;
    public final int depth;
    public final boolean alphaPresent;
    public final int frameCount;
    public final int repetitionCount;
    public final double frameDuration;
    public final int threads;

    public Image(
        String filename,
        int width,
        int height,
        int depth,
        boolean alphaPresent,
        int frameCount,
        int repetitionCount,
        double frameDuration,
        int threads) {
      this.filename = filename;
      this.width = width;
      this.height = height;
      this.depth = depth;
      this.alphaPresent = alphaPresent;
      this.frameCount = frameCount;
      this.repetitionCount = repetitionCount;
      this.frameDuration = frameDuration;
      this.threads = threads;
    }
  }

  private static final Image[] IMAGES = {
    // Parameter ordering: filename, width, height, depth, alphaPresent, frameCount,
    // repetitionCount, frameDuration, threads.
    new Image("alpha_video.avif", 640, 480, 8, true, 48, -2, 0.04, 1),
    new Image("Chimera-AV1-10bit-480x270.avif", 480, 270, 10, false, 95, -2, 0.04, 2),
  };

  private static final String ASSET_DIRECTORY = "animated_avif";

  private static final Bitmap.Config[] BITMAP_CONFIGS = {
    // RGBA_F16 is not tested because x86 emulators are flaky with that.
    Config.ARGB_8888, Config.RGB_565,
  };

  @Parameters
  public static List<Object[]> data() throws IOException {
    ArrayList<Object[]> list = new ArrayList<>();
    for (Bitmap.Config config : BITMAP_CONFIGS) {
      for (Image image : IMAGES) {
        list.add(new Object[] {config, image});
      }
    }
    return list;
  }

  @Parameter(0)
  public Bitmap.Config config;

  @Parameter(1)
  public Image image;

  @Test
  public void testAnimatedAvifDecode() throws IOException {
    ByteBuffer buffer = getBuffer();
    assertThat(buffer).isNotNull();
    AvifDecoder decoder = AvifDecoder.create(buffer, image.threads);
    assertThat(decoder).isNotNull();
    assertThat(decoder.getWidth()).isEqualTo(image.width);
    assertThat(decoder.getHeight()).isEqualTo(image.height);
    assertThat(decoder.getDepth()).isEqualTo(image.depth);
    assertThat(decoder.getAlphaPresent()).isEqualTo(image.alphaPresent);
    assertThat(decoder.getFrameCount()).isEqualTo(image.frameCount);
    assertThat(decoder.getRepetitionCount()).isEqualTo(image.repetitionCount);
    double[] frameDurations = decoder.getFrameDurations();
    assertThat(frameDurations).isNotNull();
    assertThat(frameDurations).hasLength(image.frameCount);
    Bitmap bitmap = Bitmap.createBitmap(image.width, image.height, config);
    assertThat(bitmap).isNotNull();
    for (int i = 0; i < image.frameCount; i++) {
      assertThat(decoder.nextFrameIndex()).isEqualTo(i);
      assertThat(decoder.nextFrame(bitmap)).isEqualTo(AVIF_RESULT_OK);
      assertThat(frameDurations[i]).isWithin(1.0e-2).of(image.frameDuration);
    }
    assertThat(decoder.nextFrameIndex()).isEqualTo(image.frameCount);
    // Fetch the first frame again.
    assertThat(decoder.nthFrame(0, bitmap)).isEqualTo(AVIF_RESULT_OK);
    // Now nextFrame will return the second frame.
    assertThat(decoder.nextFrameIndex()).isEqualTo(1);
    assertThat(decoder.nextFrame(bitmap)).isEqualTo(AVIF_RESULT_OK);
    // Fetch the (frameCount/2)th frame.
    assertThat(decoder.nthFrame(image.frameCount / 2, bitmap)).isEqualTo(AVIF_RESULT_OK);
    // Fetch the last frame.
    assertThat(decoder.nthFrame(image.frameCount - 1, bitmap)).isEqualTo(AVIF_RESULT_OK);
    // Now nextFrame should return false.
    assertThat(decoder.nextFrameIndex()).isEqualTo(image.frameCount);
    assertThat(decoder.nextFrame(bitmap)).isNotEqualTo(AVIF_RESULT_OK);
    // Passing out of bound values for n should fail.
    assertThat(decoder.nthFrame(-1, bitmap)).isNotEqualTo(AVIF_RESULT_OK);
    assertThat(decoder.nthFrame(image.frameCount, bitmap)).isNotEqualTo(AVIF_RESULT_OK);
    decoder.release();
  }

  @Test
  public void testUtilityFunctions() throws IOException {
    // Test the avifResult value whose value and string representations are least likely to change.
    assertThat(AvifDecoder.resultToString(AVIF_RESULT_OK)).isEqualTo("OK");
    // Ensure that the version string starts with "libavif".
    assertThat(AvifDecoder.versionString()).startsWith("libavif");
  }

  private ByteBuffer getBuffer() throws IOException {
    Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
    String assetPath = Paths.get(ASSET_DIRECTORY, image.filename).toString();
    InputStream is = context.getAssets().open(assetPath);
    ByteBuffer buffer = ByteBuffer.allocateDirect(is.available());
    Channels.newChannel(is).read(buffer);
    buffer.rewind();
    return buffer;
  }
}
