// Copyright (c) 2017, 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;

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

import com.android.tools.r8.ToolHelper.ArtCommandBuilder;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.QuadConsumer;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.junit.Assert;

public class AsmTestBase extends TestBase {

  protected void ensureSameOutput(String main, AndroidApiLevel apiLevel, byte[]... classes)
      throws Exception {
    ensureSameOutput(main, apiLevel, Collections.emptyList(), classes);
  }

  protected void ensureSameOutput(String main, AndroidApiLevel apiLevel,
      List<String> args, byte[]... classes) throws Exception {
    AndroidApp app = buildAndroidApp(classes);
    Consumer<InternalOptions> setMinApiLevel = o -> o.setMinApiLevel(apiLevel);
    ProcessResult javaResult = runOnJavaRaw(main, Arrays.asList(classes), args);
    Consumer<ArtCommandBuilder> cmdBuilder = builder -> {
      for (String arg : args) {
        builder.appendProgramArgument(arg);
      }
    };
    ProcessResult d8Result = runOnArtRaw(
        compileWithD8(app, setMinApiLevel), main, cmdBuilder, null);
    ProcessResult r8Result = runOnArtRaw(
        compileWithR8(app, setMinApiLevel), main, cmdBuilder, null);
    ProcessResult r8ShakenResult = runOnArtRaw(
        compileWithR8(app, keepMainProguardConfiguration(main) + "-dontobfuscate\n",
            setMinApiLevel), main, cmdBuilder, null);
    Assert.assertEquals(javaResult.stdout, d8Result.stdout);
    Assert.assertEquals(javaResult.stdout, r8Result.stdout);
    Assert.assertEquals(javaResult.stdout, r8ShakenResult.stdout);
  }

  protected void ensureCustomCheck(
      QuadConsumer<ProcessResult, ProcessResult, ProcessResult, ProcessResult> checker,
      String main,
      AndroidApiLevel apiLevel,
      List<String> args,
      byte[]... classes)
      throws Exception {
    AndroidApp app = buildAndroidApp(classes);
    Consumer<InternalOptions> setMinApiLevel = o -> o.setMinApiLevel(apiLevel);
    ProcessResult javaResult = runOnJavaRaw(main, Arrays.asList(classes), args);
    Consumer<ArtCommandBuilder> cmdBuilder =
        builder -> {
          for (String arg : args) {
            builder.appendProgramArgument(arg);
          }
        };
    ProcessResult d8Result =
        runOnArtRaw(compileWithD8(app, setMinApiLevel), main, cmdBuilder, null);
    ProcessResult r8Result =
        runOnArtRaw(compileWithR8(app, setMinApiLevel), main, cmdBuilder, null);
    ProcessResult r8ShakenResult =
        runOnArtRaw(
            compileWithR8(
                app, keepMainProguardConfiguration(main) + "-dontobfuscate\n", setMinApiLevel),
            main,
            cmdBuilder,
            null);
    checker.accept(javaResult, d8Result, r8Result, r8ShakenResult);
  }

  protected void ensureSameOutput(String main, byte[]... classes) throws Exception {
    AndroidApp app = buildAndroidApp(classes);
    ensureSameOutput(main, app, false, classes);
  }

  protected void ensureSameOutputJavaNoVerify(String main, byte[]... classes) throws Exception {
    AndroidApp app = buildAndroidApp(classes);
    ensureSameOutput(main, app, true, classes);
  }

  private void ensureSameOutput(
      String main, AndroidApp app, boolean useJavaNoVerify, byte[]... classes)
      throws IOException, CompilationFailedException {
    ProcessResult javaResult =
        useJavaNoVerify ? runOnJavaRawNoVerify(main, classes) : runOnJavaRaw(main, classes);
    ProcessResult d8Result = runOnArtRaw(compileWithD8(app), main);
    ProcessResult r8NonShakenResult =
        runOnArtRaw(compileWithR8(app, "-dontshrink\n-dontobfuscate\n"), main);
    ProcessResult r8ShakenResult =
        runOnArtRaw(
            compileWithR8(app, keepMainProguardConfiguration(main) + "-dontobfuscate\n"), main);
    Assert.assertEquals(javaResult.stdout, d8Result.stdout);
    Assert.assertEquals(javaResult.stdout, r8NonShakenResult.stdout);
    Assert.assertEquals(javaResult.stdout, r8ShakenResult.stdout);
    Assert.assertEquals(0, javaResult.exitCode);
    Assert.assertEquals(0, d8Result.exitCode);
    Assert.assertEquals(0, r8NonShakenResult.exitCode);
    Assert.assertEquals(0, r8ShakenResult.exitCode);
  }

  protected void ensureR8FailsWithCompilationError(String main, byte[]... classes)
      throws Exception {
    // TODO(zerny): Port this to use diagnostics handler.
    AndroidApp app = buildAndroidApp(classes);
    CompilationFailedException r8Error = null;
    CompilationFailedException r8ShakenError = null;
    try {
      runOnArtRaw(compileWithR8(app, "-dontshrink\n-dontobfuscate\n"), main);
    } catch (CompilationFailedException e) {
      r8Error = e;
    }
    try {
      runOnArtRaw(compileWithR8(app, keepMainProguardConfiguration(main) + "-dontobfuscate\n"),
          main);
    } catch (CompilationFailedException e) {
      r8ShakenError = e;
    }
    Assert.assertNotNull(r8Error);
    Assert.assertNotNull(r8ShakenError);
  }

  protected void ensureSameOutputAfterMerging(String main, byte[]... classes)
      throws IOException, CompilationFailedException {
    AndroidApp app = buildAndroidApp(classes);
    // Compile to dex files with D8.
    AndroidApp dexApp = compileWithD8(app);
    // Perform dex merging with D8 to read the dex files.
    AndroidApp mergedApp = compileWithD8(dexApp);
    ensureSameOutput(main, mergedApp, false, classes);
  }

  protected static AndroidApp readClassesAndAsmDump(List<Class<?>> classes, List<byte[]> asmClasses)
      throws IOException {
    AndroidApp.Builder builder = AndroidApp.builder();
    for (Class clazz : classes) {
      builder.addProgramFiles(ToolHelper.getClassFileForTestClass(clazz));
    }
    for (byte[] clazz : asmClasses) {
      builder.addClassProgramData(clazz, Origin.unknown());
    }
    return builder.build();
  }

  private void ensureExceptionThrown(ProcessResult result, Class<? extends Throwable> exception) {
    assertFalse(result.stdout, result.exitCode == 0);
    assertTrue(result.stderr, result.stderr.contains(exception.getCanonicalName()));
  }

  @FunctionalInterface
  protected interface AsmDump {

    byte[] dump() throws Exception;
  }

  protected static byte[] getBytesFromAsmClass(AsmDump asmDump) {
    try {
      return asmDump.dump();
    } catch (Exception e) {
      throw new ClassFormatError(e.toString());
    }
  }
}
