// 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.ProcessResult;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.ProguardRuleParserException;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.io.ByteStreams;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.ExecutionException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.junit.Assert;

public class AsmTestBase extends TestBase {

  protected void ensureException(String main, Class<? extends Throwable> exceptionClass,
      byte[]... classes) throws Exception {
    ensureExceptionThrown(runOnJava(main, classes), exceptionClass);
    AndroidApp app = buildAndroidApp(classes);
    ensureExceptionThrown(runOnArtRaw(compileWithD8(app), main), exceptionClass);
    ensureExceptionThrown(runOnArtRaw(compileWithR8(app), main), exceptionClass);
    ensureExceptionThrown(
        runOnArtRaw(compileWithR8(app, keepMainProguardConfiguration(main) + "-dontobfuscate\n"),
            main),
        exceptionClass);
  }

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

  private void ensureSameOutput(String main, AndroidApp app, byte[]... classes)
      throws IOException, CompilationException, ExecutionException, CompilationFailedException,
      ProguardRuleParserException {
    ProcessResult javaResult = runOnJava(main, classes);
    ProcessResult d8Result = runOnArtRaw(compileWithD8(app), main);
    ProcessResult r8Result = runOnArtRaw(compileWithR8(app), main);
    ProcessResult r8ShakenResult = runOnArtRaw(
        compileWithR8(app, keepMainProguardConfiguration(main) + "-dontobfuscate\n"), main);
    Assert.assertEquals(javaResult.stdout, d8Result.stdout);
    Assert.assertEquals(javaResult.stdout, r8Result.stdout);
    Assert.assertEquals(javaResult.stdout, r8ShakenResult.stdout);
  }

  protected void ensureSameOutputD8R8(String main, byte[]... classes) throws Exception {
    AndroidApp app = buildAndroidApp(classes);
    ProcessResult d8Result = runOnArtRaw(compileWithD8(app), main);
    ProcessResult r8Result = runOnArtRaw(compileWithR8(app), main);
    ProcessResult r8ShakenResult = runOnArtRaw(
        compileWithR8(app, keepMainProguardConfiguration(main) + "-dontobfuscate\n"), main);
    Assert.assertEquals(d8Result.stdout, r8Result.stdout);
    Assert.assertEquals(d8Result.stdout, r8ShakenResult.stdout);
  }

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

  protected void ensureSameOutputAfterMerging(String main, byte[]... classes)
      throws IOException, CompilationException, ExecutionException,
      CompilationFailedException, ProguardRuleParserException {
    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, classes);
  }

  protected byte[] asBytes(Class clazz) throws IOException {
    return ByteStreams
        .toByteArray(clazz.getResourceAsStream(clazz.getSimpleName() + ".class"));
  }

  private AndroidApp buildAndroidApp(byte[]... classes) throws IOException {
    AndroidApp.Builder builder = AndroidApp.builder();
    for (byte[] clazz : classes) {
      builder.addClassProgramData(clazz, Origin.unknown());
    }
    builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.N.getLevel()));
    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()));
  }

  protected ProcessResult runOnJava(String main, byte[]... classes) throws IOException {
    Path file = writeToZip(classes);
    return ToolHelper.runJavaNoVerify(file, main);
  }

  private Path writeToZip(byte[]... classes) throws IOException {
    NameExtrator nameExtrator = new NameExtrator();
    File result = temp.newFile();
    try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(result.toPath(),
        StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING))) {
      for (byte[] clazz : classes) {
        String name = nameExtrator.getName(clazz);
        ZipEntry zipEntry = new ZipEntry(DescriptorUtils.getPathFromJavaType(name));
        zipEntry.setSize(clazz.length);
        out.putNextEntry(zipEntry);
        out.write(clazz);
        out.closeEntry();
      }
    }
    return result.toPath();
  }

  private static class NameExtrator extends ClassLoader {

    public String getName(byte[] clazz) {
      Class loaded = defineClass(clazz, 0, clazz.length);
      return loaded.getTypeName();
    }
  }
}
