// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.debug;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.ProgramConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.R8Command.Builder;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.DebuggeeState;
import com.android.tools.r8.origin.Origin;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.stream.Stream;
import org.junit.Assume;
import org.junit.Test;

public class IincDebugTestRunner extends DebugTestBase {
  @Test
  public void compareDifferentRegister() throws Exception {
    compareOutput(IincDebugTestDump.dump(1, 2, false));
  }

  @Test
  public void compareLoadStoreSameRegister() throws Exception {
    compareOutput(IincDebugTestDump.dump(1, 1, false));
  }

  @Test
  public void compareIinc() throws Exception {
    compareOutput(IincDebugTestDump.dump(1, 1, true));
  }

  @Test
  public void stepDifferentRegister() throws Exception {
    stepOutput(IincDebugTestDump.dump(1, 2, false));
  }

  @Test
  public void stepLoadStoreSameRegister() throws Exception {
    stepOutput(IincDebugTestDump.dump(1, 1, false));
  }

  @Test
  public void stepIinc() throws Exception {
    stepOutput(IincDebugTestDump.dump(1, 1, true));
  }

  private void compareOutput(byte[] clazz) throws Exception {
    Path inputJar = buildInput(clazz);
    ProcessResult runInput = ToolHelper.runJava(inputJar, IincDebugTestDump.CLASS_NAME);
    assertEquals(0, runInput.exitCode);
    ProcessResult runCf = ToolHelper.runJava(buildCf(inputJar), IincDebugTestDump.CLASS_NAME);
    assertEquals(0, runCf.exitCode);
    assertEquals(runInput.toString(), runCf.toString());
    String runDex =
        ToolHelper.runArtNoVerificationErrors(
            buildDex(inputJar).toString(), IincDebugTestDump.CLASS_NAME);
    assertEquals(runInput.stdout, runDex);
  }

  private void stepOutput(byte[] clazz) throws Exception {
    // See verifyStateLocation in DebugTestBase.
    Assume.assumeTrue(
        "Streaming on Dalvik DEX runtimes has some unknown interference issue",
        ToolHelper.getDexVm().getVersion().isAtLeast(Version.V6_0_1));
    Assume.assumeTrue(
        "Skipping test "
            + testName.getMethodName()
            + " because debug tests are not yet supported on Windows",
        !ToolHelper.isWindows());
    Path inputJar = buildInput(clazz);
    new DebugStreamComparator()
        .add("Input", streamDebugTest(new CfDebugTestConfig(inputJar)))
        .add("R8/DEX", streamDebugTest(new DexDebugTestConfig(buildDex(inputJar))))
        .add("R8/CF", streamDebugTest(new CfDebugTestConfig(buildCf(inputJar))))
        .compare();
  }

  private Stream<DebuggeeState> streamDebugTest(DebugTestConfig config) throws Exception {
    return streamDebugTest(config, IincDebugTestDump.CLASS_NAME, ANDROID_FILTER);
  }

  private Path buildInput(byte[] clazz) {
    Path inputJar = temp.getRoot().toPath().resolve("input.jar");
    ArchiveConsumer inputJarConsumer = new ArchiveConsumer(inputJar);
    inputJarConsumer.accept(ByteDataView.of(clazz), IincDebugTestDump.DESCRIPTOR, null);
    inputJarConsumer.finished(null);
    return inputJar;
  }

  private Path buildDex(Path inputJar) throws Exception {
    Path dexJar = temp.getRoot().toPath().resolve("r8dex.jar");
    build(inputJar, new DexIndexedConsumer.ArchiveConsumer(dexJar));
    return dexJar;
  }

  private Path buildCf(Path inputJar) throws Exception {
    Path cfJar = temp.getRoot().toPath().resolve("r8cf.jar");
    build(inputJar, new ArchiveConsumer(cfJar));
    return cfJar;
  }

  private void build(Path inputJar, ProgramConsumer consumer) throws Exception {
    Builder builder =
        R8Command.builder()
            .setMode(CompilationMode.DEBUG)
            .setDisableTreeShaking(true)
            .setDisableMinification(true)
            .addProguardConfiguration(
                ImmutableList.of("-keepattributes SourceFile,LineNumberTable"), Origin.unknown())
            .setProgramConsumer(consumer)
            .addProgramFiles(inputJar);
    if ((consumer instanceof ClassFileConsumer)) {
      builder.addLibraryFiles(ToolHelper.getJava8RuntimeJar());
    } else {
      builder.addLibraryFiles(ToolHelper.getAndroidJar(ToolHelper.getMinApiLevelForDexVm()));
    }
    ToolHelper.runR8(builder.build(), options -> options.invalidDebugInfoFatal = true);
  }
}
