// 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.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.Paths;
import java.nio.file.StandardOpenOption;
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 {
    ProcessResult javaResult = runOnJava(main, classes);
    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(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 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(Paths.get(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.getCanonicalName();
    }
  }
}
