// 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;

import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
import static com.google.common.io.ByteStreams.toByteArray;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import org.junit.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.util.ASMifier;
import org.objectweb.asm.util.TraceClassVisitor;

public class CfFrontendExamplesTest extends TestBase {

  @Test
  public void testArithmetic() throws Exception {
    runTest("arithmetic.Arithmetic");
  }

  @Test
  public void testArrayAccess() throws Exception {
    runTest("arrayaccess.ArrayAccess");
  }

  @Test
  public void testBArray() throws Exception {
    runTest("barray.BArray");
  }

  @Test
  public void testBridgeMethod() throws Exception {
    runTest("bridge.BridgeMethod");
  }

  @Test
  public void testCommonSubexpressionElimination() throws Exception {
    runTest("cse.CommonSubexpressionElimination");
  }

  @Test
  public void testConstants() throws Exception {
    runTest("constants.Constants");
  }

  @Test
  public void testControlFlow() throws Exception {
    runTest("controlflow.ControlFlow");
  }

  @Test
  public void testConversions() throws Exception {
    runTest("conversions.Conversions");
  }

  @Test
  public void testFloatingPointValuedAnnotation() throws Exception {
    runTest("floating_point_annotations.FloatingPointValuedAnnotationTest");
  }

  @Test
  public void testFilledArray() throws Exception {
    runTest("filledarray.FilledArray");
  }

  @Test
  public void testHello() throws Exception {
    runTest("hello.Hello");
  }

  @Test
  public void testIfStatements() throws Exception {
    runTest("ifstatements.IfStatements");
  }

  @Test
  public void testInlining() throws Exception {
    runTest("inlining.Inlining");
  }

  @Test
  public void testInstanceVariable() throws Exception {
    runTest("instancevariable.InstanceVariable");
  }

  @Test
  public void testInstanceofString() throws Exception {
    runTest("instanceofstring.InstanceofString");
  }

  @Test
  public void testInvoke() throws Exception {
    runTest("invoke.Invoke");
  }

  @Test
  public void testJumboString() throws Exception {
    runTest("jumbostring.JumboString");
  }

  @Test
  public void testLoadConst() throws Exception {
    runTest("loadconst.LoadConst");
  }

  @Test
  public void testUdpServer() throws Exception {
    runTest("loop.UdpServer");
  }

  @Test
  public void testRegAlloc() throws Exception {
    runTest("regalloc.RegAlloc");
  }

  @Test
  public void testReturns() throws Exception {
    runTest("returns.Returns");
  }

  @Test
  public void testStaticField() throws Exception {
    runTest("staticfield.StaticField");
  }

  @Test
  public void testStringBuilding() throws Exception {
    runTest("stringbuilding.StringBuilding");
  }

  @Test
  public void testSwitches() throws Exception {
    runTest("switches.Switches");
  }

  @Test
  public void testSync() throws Exception {
    runTest("sync.Sync");
  }

  @Test
  public void testThrowing() throws Exception {
    runTest("throwing.Throwing");
  }

  @Test
  public void testTrivial() throws Exception {
    runTest("trivial.Trivial");
  }

  @Test
  public void testTryCatch() throws Exception {
    runTest("trycatch.TryCatch");
  }

  @Test
  public void testNestedTryCatches() throws Exception {
    runTest("nestedtrycatches.NestedTryCatches");
  }

  @Test
  public void testTryCatchMany() throws Exception {
    runTest("trycatchmany.TryCatchMany");
  }

  @Test
  public void testInvokeEmpty() throws Exception {
    runTest("invokeempty.InvokeEmpty");
  }

  @Test
  public void testRegress() throws Exception {
    runTest("regress.Regress");
  }

  @Test
  public void testRegress2() throws Exception {
    runTest("regress2.Regress2");
  }

  @Test
  public void testRegress37726195() throws Exception {
    runTest("regress_37726195.Regress");
  }

  @Test
  public void testRegress37658666() throws Exception {
    runTest(
        "regress_37658666.Regress",
        (expected, actual) -> {
          // javac emits LDC(-0.0f) instead of the shorter FCONST_0 FNEG emitted by CfConstNumber.
          String ldc = "methodVisitor.visitLdcInsn(new Float(\"-0.0\"));";
          String constNeg = "methodVisitor.visitInsn(FCONST_0);\nmethodVisitor.visitInsn(FNEG);";
          assertEquals(expected.replace(ldc, constNeg), actual);
        });
  }

  @Test
  public void testRegress37875803() throws Exception {
    runTest("regress_37875803.Regress");
  }

  @Test
  public void testRegress37955340() throws Exception {
    runTest("regress_37955340.Regress");
  }

  @Test
  public void testRegress62300145() throws Exception {
    runTest("regress_62300145.Regress");
  }

  @Test
  public void testRegress64881691() throws Exception {
    runTest("regress_64881691.Regress");
  }

  @Test
  public void testRegress65104300() throws Exception {
    runTest("regress_65104300.Regress");
  }

  @Test
  public void testRegress70703087() throws Exception {
    runTest("regress_70703087.Test");
  }

  @Test
  public void testRegress70736958() throws Exception {
    runTest("regress_70736958.Test");
  }

  @Test
  public void testRegress70737019() throws Exception {
    runTest("regress_70737019.Test");
  }

  @Test
  public void testRegress72361252() throws Exception {
    runTest("regress_72361252.Test");
  }

  @Test
  public void testMemberrebinding2() throws Exception {
    runTest("memberrebinding2.Memberrebinding");
  }

  @Test
  public void testMemberrebinding3() throws Exception {
    runTest("memberrebinding3.Memberrebinding");
  }

  @Test
  public void testMinification() throws Exception {
    runTest("minification.Minification");
  }

  @Test
  public void testEnclosingmethod() throws Exception {
    runTest("enclosingmethod.Main");
  }

  @Test
  public void testEnclosingmethodProguarded() throws Exception {
    runTest("enclosingmethod_proguarded.Main");
  }

  @Test
  public void testInterfaceInlining() throws Exception {
    runTest("interfaceinlining.Main");
  }

  @Test
  public void testSwitchmaps() throws Exception {
    runTest("switchmaps.Switches");
  }

  private void runTest(String clazz) throws Exception {
    runTest(
        clazz, (expected, actual) -> assertEquals("Class " + clazz + " differs", expected, actual));
  }

  private void runTest(String clazz, BiConsumer<String, String> comparator) throws Exception {
    assert comparator != null;
    String pkg = clazz.substring(0, clazz.lastIndexOf('.'));
    String suffix = "_debuginfo_all";
    Path inputJar = Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, pkg + suffix + JAR_EXTENSION);
    Path outputJar = temp.getRoot().toPath().resolve("output.jar");
    R8Command command =
        R8Command.builder()
            .addProgramFiles(inputJar)
            .addLibraryFiles(ToolHelper.getJava8RuntimeJar())
            .setMode(CompilationMode.DEBUG)
            .setDisableTreeShaking(true)
            .setDisableMinification(true)
            .addProguardConfiguration(ImmutableList.of("-keepattributes *"), Origin.unknown())
            .setOutput(outputJar, OutputMode.ClassFile)
            .build();
    ToolHelper.runR8(
        command,
        options -> {
          options.skipIR = true;
          options.testing.readInputStackMaps = true;
        });
    ArchiveClassFileProvider expected = new ArchiveClassFileProvider(inputJar);
    ArchiveClassFileProvider actual = new ArchiveClassFileProvider(outputJar);
    assertEquals(getSortedDescriptorList(expected), getSortedDescriptorList(actual));
    for (String descriptor : expected.getClassDescriptors()) {
      byte[] expectedBytes = getClassAsBytes(expected, descriptor);
      byte[] actualBytes = getClassAsBytes(actual, descriptor);
      if (!Arrays.equals(expectedBytes, actualBytes)) {
        String expectedString = replaceCatchThrowableByCatchAll(asmToString(expectedBytes));
        String actualString = asmToString(actualBytes);
        comparator.accept(expectedString, actualString);
      }
    }
  }

  private static String replaceCatchThrowableByCatchAll(String content) {
    String catchThrowablePrefix = "methodVisitor.visitTryCatchBlock(";
    String catchThrowableSuffix = ", \"java/lang/Throwable\");";
    StringBuilder expected = new StringBuilder();
    List<String> expectedLines = StringUtils.splitLines(content);
    for (String line : expectedLines) {
      if (line.startsWith(catchThrowablePrefix) && line.endsWith(catchThrowableSuffix)) {
        expected.append(line.replace("\"java/lang/Throwable\"", "null"));
      } else {
        expected.append(line);
      }
      expected.append('\n');
    }
    return expected.toString();
  }

  private static List<String> getSortedDescriptorList(ArchiveClassFileProvider inputJar) {
    ArrayList<String> descriptorList = new ArrayList<>(inputJar.getClassDescriptors());
    Collections.sort(descriptorList);
    return descriptorList;
  }

  private static byte[] getClassAsBytes(ArchiveClassFileProvider inputJar, String descriptor)
      throws Exception {
    return toByteArray(inputJar.getProgramResource(descriptor).getByteStream());
  }

  private static String asmToString(byte[] clazz) {
    StringWriter stringWriter = new StringWriter();
    printAsm(new PrintWriter(stringWriter), clazz);
    return stringWriter.toString();
  }

  private static void printAsm(PrintWriter pw, byte[] clazz) {
    new ClassReader(clazz).accept(new TraceClassVisitor(null, new ASMifierSorted(), pw), 0);
  }

  /** Sort methods and fields in the output of ASMifier to make diffing possible. */
  private static class ASMifierSorted extends ASMifier {
    private static class Part implements Comparable<Part> {

      private final String key;
      private final int start;
      private final int end;

      Part(String key, int start, int end) {
        this.key = key;
        this.start = start;
        this.end = end;
      }

      @Override
      public int compareTo(Part part) {
        int i = key.compareTo(part.key);
        return i != 0 ? i : Integer.compare(start, part.start);
      }
    }

    private final List<Part> parts = new ArrayList<>();

    ASMifierSorted() {
      super(InternalOptions.ASM_VERSION, "cw", 0);
    }

    @Override
    public ASMifier visitField(
        int access, String name, String desc, String signature, Object value) {
      init();
      int i = text.size();
      ASMifier res = super.visitField(access, name, desc, signature, value);
      parts.add(new Part((String) text.get(i), i, text.size()));
      return res;
    }

    @Override
    public ASMifier visitMethod(
        int access, String name, String desc, String signature, String[] exceptions) {
      init();
      int i = text.size();
      ASMifier res = super.visitMethod(access, name, desc, signature, exceptions);
      parts.add(new Part((String) text.get(i), i, text.size()));
      return res;
    }

    private void init() {
      if (parts.isEmpty()) {
        parts.add(new Part("", 0, text.size()));
      }
    }

    @Override
    public void print(PrintWriter pw) {
      init();
      int end = parts.get(parts.size() - 1).end;
      Collections.sort(parts);
      parts.add(new Part("", end, text.size()));
      ArrayList<Object> tmp = new ArrayList<>(text);
      text.clear();
      for (Part part : parts) {
        for (int i = part.start; i < part.end; i++) {
          text.add(tmp.get(i));
        }
      }
      super.print(pw);
    }
  }
}
