// 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.kotlin.lambda;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;

import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.optimize.lambda.CaptureSignature;
import com.android.tools.r8.kotlin.AbstractR8KotlinTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.Lists;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class KotlinLambdaMergingTest extends AbstractR8KotlinTestBase {
  private static final String KOTLIN_FUNCTION_IFACE = "Lkotlin/jvm/functions/Function";
  private static final String KOTLIN_FUNCTION_IFACE_STR = "kotlin.jvm.functions.Function";
  private static final String KEEP_INNER_AND_ENCLOSING =
      "-keepattributes InnerClasses,EnclosingMethod\n";
  private static final String KEEP_SIGNATURE_INNER_ENCLOSING =
      "-keepattributes Signature,InnerClasses,EnclosingMethod\n";

  private Consumer<InternalOptions> getOptionsModifier() {
    return opts -> {
      opts.enableClassInlining = false;
      opts.enableUnusedArgumentRemoval = false;
      // The test checks that the generated lambdas inherit from Function, which is not true if
      // the unused interface removal is enabled.
      opts.enableUnusedInterfaceRemoval = enableUnusedInterfaceRemoval;
      // Ensure that enclosing method and inner class attributes are kept even on classes that are
      // not explicitly mentioned by a keep rule.
      opts.forceProguardCompatibility = true;
    };
  }

  private final boolean enableUnusedInterfaceRemoval;

  @Parameterized.Parameters(
      name = "target: {0}, allow access modification: {1}, unused interface removal: {2}")
  public static Collection<Object[]> data() {
    return buildParameters(
        KotlinTargetVersion.values(), BooleanUtils.values(), BooleanUtils.values());
  }

  public KotlinLambdaMergingTest(
      KotlinTargetVersion targetVersion,
      boolean allowAccessModification,
      boolean enableUnusedInterfaceRemoval) {
    super(targetVersion, allowAccessModification);
    this.enableUnusedInterfaceRemoval = enableUnusedInterfaceRemoval;
  }

  abstract static class LambdaOrGroup {
    abstract boolean match(DexClass clazz);
  }

  static class Group extends LambdaOrGroup {
    final String pkg;
    final String capture;
    final int arity;
    final String sam;
    final int singletons;

    private Group(String pkg, String capture, int arity, String sam, int singletons) {
      this.pkg = pkg;
      this.capture = fixCapture(capture);
      this.arity = arity;
      this.sam = sam;
      this.singletons = singletons;
    }

    private String fixCapture(String capture) {
      capture += "I";
      char[] chars = capture.toCharArray();
      Arrays.sort(chars);
      return new String(chars);
    }

    @Override
    public String toString() {
      return "group class " +
          (pkg.length() == 0 ? "" : pkg + "/") +
          "-$$LambdaGroup$XXXX (arity: " + arity +
          ", capture: " + capture + ", iface: " + sam + ", sing: " + singletons + ")";
    }

    @Override
    boolean match(DexClass clazz) {
      return clazz.type.getPackageDescriptor().equals(pkg) &&
          getLambdaOrGroupCapture(clazz).equals(capture) &&
          getLambdaSam(clazz).equals(sam) &&
          getLambdaSingletons(clazz) == singletons &&
          getLambdaOrGroupArity(clazz) == arity;
    }
  }

  private static Group kstyleImpl(String pkg, String capture, int arity, int singletons) {
    assertEquals(capture.isEmpty(), singletons != 0);
    return new Group(pkg, capture, arity, KOTLIN_FUNCTION_IFACE_STR + arity, singletons);
  }

  static Group kstyle(String pkg, int arity, int singletons) {
    assertTrue(singletons != 0);
    return kstyleImpl(pkg, "", arity, singletons);
  }

  private static Group kstyle(String pkg, String capture, int arity) {
    assertFalse(capture.isEmpty());
    return kstyleImpl(pkg, capture, arity, 0);
  }

  private static Group jstyleImpl(
      String pkg, String capture, int arity, String sam, int singletons) {
    assertTrue(capture.isEmpty() || singletons == 0);
    return new Group(pkg, capture, arity, sam, singletons);
  }

  private static Group jstyle(String pkg, String capture, int arity, String sam) {
    return jstyleImpl(pkg, capture, arity, sam, 0);
  }

  private static Group jstyle(String pkg, int arity, String sam, int singletons) {
    return jstyleImpl(pkg, "", arity, sam, singletons);
  }

  static class Lambda extends LambdaOrGroup {
    final String pkg;
    final String name;
    final int arity;

    Lambda(String pkg, String name, int arity) {
      this.pkg = pkg;
      this.name = name;
      this.arity = arity;
    }

    @Override
    public String toString() {
      return "lambda class " +
          (pkg.length() == 0 ? "" : pkg + "/") +
          name + " (arity: " + arity + ")";
    }

    @Override
    boolean match(DexClass clazz) {
      return clazz.type.getPackageDescriptor().equals(pkg) &&
          clazz.type.getName().equals(name) &&
          getLambdaOrGroupArity(clazz) == arity;
    }
  }

  static class Verifier {
    final CodeInspector codeInspector;
    final List<DexClass> lambdas = new ArrayList<>();
    final List<DexClass> groups = new ArrayList<>();

    Verifier(AndroidApp app) throws IOException, ExecutionException {
      this(new CodeInspector(app));
    }

    Verifier(CodeInspector codeInspector) {
      this.codeInspector = codeInspector;
      initGroupsAndLambdas();
    }

    private void initGroupsAndLambdas() {
      codeInspector.forAllClasses(clazz -> {
        DexClass dexClass = clazz.getDexClass();
        if (isLambdaOrGroup(dexClass)) {
          if (isLambdaGroupClass(dexClass)) {
            groups.add(dexClass);
          } else {
            lambdas.add(dexClass);
          }
        }
      });
    }

    void assertLambdaGroups(Group... groups) {
      assertLambdasOrGroups("Lambda group", this.groups, groups);
    }

    void assertLambdas(Lambda... lambdas) {
      assertLambdasOrGroups("Lambda", this.lambdas, lambdas);
    }

    @SafeVarargs
    private static <T extends LambdaOrGroup>
    void assertLambdasOrGroups(String what, List<DexClass> objects, T... checks) {
      ArrayList<DexClass> list = Lists.newArrayList(objects);
      for (int i = 0; i < checks.length; i++) {
        T check = checks[i];
        for (DexClass clazz : list) {
          if (check.match(clazz)) {
            // Validate static initializer.
            if (check instanceof Group) {
              assertEquals(clazz.directMethods().size(), ((Group) check).singletons == 0 ? 1 : 2);
            }

            list.remove(clazz);
            checks[i] = null;
            break;
          }
        }
      }

      int notFound = 0;
      for (T check : checks) {
        if (check != null) {
          System.err.println(what + " not found: " + check);
          notFound++;
        }
      }

      for (DexClass dexClass : list) {
        System.err.println(what + " unexpected: " +
            dexClass.type.descriptor.toString() +
            ", arity: " + getLambdaOrGroupArity(dexClass) +
            ", capture: " + getLambdaOrGroupCapture(dexClass) +
            ", sam: " + getLambdaSam(dexClass) +
            ", sing: " + getLambdaSingletons(dexClass));
        notFound++;
      }

      assertTrue(what + "s match failed", 0 == notFound && 0 == list.size());
    }
  }

  private static int getLambdaOrGroupArity(DexClass clazz) {
    if (isKStyleLambdaOrGroup(clazz)) {
      for (DexType iface : clazz.interfaces.values) {
        String descr = iface.descriptor.toString();
        if (descr.startsWith(KOTLIN_FUNCTION_IFACE)) {
          return Integer.parseInt(
              descr.substring(KOTLIN_FUNCTION_IFACE.length(), descr.length() - 1));
        }
      }

    } else {
      assertTrue(isJStyleLambdaOrGroup(clazz));
      // Taking the number of any virtual method parameters seems to be good enough.
      assertTrue(clazz.virtualMethods().size() > 0);
      return clazz.virtualMethods().get(0).method.proto.parameters.size();
    }
    fail("Failed to get arity for " + clazz.type.descriptor.toString());
    throw new AssertionError();
  }

  private static String getLambdaSam(DexClass clazz) {
    assertEquals(1, clazz.interfaces.size());
    return clazz.interfaces.values[0].toSourceString();
  }

  private static int getLambdaSingletons(DexClass clazz) {
    assertEquals(1, clazz.interfaces.size());
    return clazz.staticFields().size();
  }

  private static boolean isLambdaOrGroup(DexClass clazz) {
    return !clazz.type.getPackageDescriptor().startsWith("kotlin") &&
        (isKStyleLambdaOrGroup(clazz) || isJStyleLambdaOrGroup(clazz));
  }

  private static boolean isKStyleLambdaOrGroup(DexClass clazz) {
    return clazz.superType.descriptor.toString().equals("Lkotlin/jvm/internal/Lambda;");
  }

  private static boolean isJStyleLambdaOrGroup(DexClass clazz) {
    return clazz.superType.descriptor.toString().equals("Ljava/lang/Object;") &&
        clazz.interfaces.size() == 1;
  }

  private static boolean isLambdaGroupClass(DexClass clazz) {
    return clazz.type.getName().startsWith("-$$LambdaGroup$");
  }

  private static String getLambdaOrGroupCapture(DexClass clazz) {
    return CaptureSignature.getCaptureSignature(clazz.instanceFields());
  }

  @Test
  public void testTrivialKs() throws Exception {
    final String mainClassName = "lambdas_kstyle_trivial.MainKt";
    runTest(
        "lambdas_kstyle_trivial",
        mainClassName,
        getOptionsModifier(),
        app -> {
          if (enableUnusedInterfaceRemoval) {
            // Only test that the code generates the same output as the input code does on the JVM.
            return;
          }

          Verifier verifier = new Verifier(app);
          String pkg = "lambdas_kstyle_trivial";

          verifier.assertLambdaGroups(
              allowAccessModification
                  ? new Group[] {
                    kstyle("", 0, 4),
                    kstyle("", 1, 9),
                    kstyle("", 2, 2), // -\
                    kstyle("", 2, 5), // - 3 groups different by main method
                    kstyle("", 2, 4), // -/
                    kstyle("", 3, 2),
                    kstyle("", 22, 2)
                  }
                  : new Group[] {
                    kstyle(pkg, 0, 2),
                    kstyle(pkg, 1, 5),
                    kstyle(pkg, 2, 5), // - 2 groups different by main method
                    kstyle(pkg, 2, 4), // -/
                    kstyle(pkg, 3, 2),
                    kstyle(pkg, 22, 2),
                    kstyle(pkg + "/inner", 0, 2),
                    kstyle(pkg + "/inner", 1, 4)
                  });

          verifier.assertLambdas(
              allowAccessModification
                  ? new Lambda[] {}
                  : new Lambda[] {
                    new Lambda(pkg, "MainKt$testStateless$8", 2),
                    new Lambda(pkg + "/inner", "InnerKt$testInnerStateless$7", 2)
                  });
        });
  }

  @Test
  public void testCapturesKs() throws Exception {
    final String mainClassName = "lambdas_kstyle_captures.MainKt";
    runTest(
        "lambdas_kstyle_captures",
        mainClassName,
        getOptionsModifier(),
        app -> {
          if (enableUnusedInterfaceRemoval) {
            // Only test that the code generates the same output as the input code does on the JVM.
            return;
          }

          Verifier verifier = new Verifier(app);
          String pkg = "lambdas_kstyle_captures";
          String grpPkg = allowAccessModification ? "" : pkg;

          verifier.assertLambdaGroups(
              kstyle(grpPkg, "LLL", 0),
              kstyle(grpPkg, "ILL", 0),
              kstyle(grpPkg, "III", 0),
              kstyle(grpPkg, "BCDFIJLLLLSZ", 0),
              kstyle(grpPkg, "BCDFIJLLSZ", 0));

          verifier.assertLambdas(
              new Lambda(pkg, "MainKt$test1$15", 0),
              new Lambda(pkg, "MainKt$test2$10", 0),
              new Lambda(pkg, "MainKt$test2$11", 0),
              new Lambda(pkg, "MainKt$test2$9", 0));
        });
  }

  @Test
  public void testGenericsNoSignatureKs() throws Exception {
    final String mainClassName = "lambdas_kstyle_generics.MainKt";
    runTest(
        "lambdas_kstyle_generics",
        mainClassName,
        getOptionsModifier(),
        app -> {
          if (enableUnusedInterfaceRemoval) {
            // Only test that the code generates the same output as the input code does on the JVM.
            return;
          }

          Verifier verifier = new Verifier(app);
          String pkg = "lambdas_kstyle_generics";
          String grpPkg = allowAccessModification ? "" : pkg;

          verifier.assertLambdaGroups(
              kstyle(grpPkg, 1, 3), // Group for Any
              kstyle(grpPkg, "L", 1), // Group for Beta
              kstyle(grpPkg, "LS", 1), // Group for Gamma
              kstyle(grpPkg, 1, 2) // Group for int
              );

          verifier.assertLambdas(new Lambda(pkg, "MainKt$main$4", 1));
        });
  }

  @Test
  public void testInnerClassesAndEnclosingMethodsKs() throws Exception {
    final String mainClassName = "lambdas_kstyle_generics.MainKt";
    runTest(
        "lambdas_kstyle_generics",
        mainClassName,
        KEEP_INNER_AND_ENCLOSING,
        getOptionsModifier(),
        app -> {
          if (enableUnusedInterfaceRemoval) {
            // Only test that the code generates the same output as the input code does on the JVM.
            return;
          }

          Verifier verifier = new Verifier(app);
          String pkg = "lambdas_kstyle_generics";
          String grpPkg = allowAccessModification ? "" : pkg;

          verifier.assertLambdaGroups(
              kstyle(grpPkg, 1, 3), // Group for Any
              kstyle(grpPkg, "L", 1), // Group for Beta   // First
              kstyle(grpPkg, "L", 1), // Group for Beta   // Second
              kstyle(grpPkg, "LS", 1), // Group for Gamma // First
              kstyle(grpPkg, "LS", 1), // Group for Gamma // Second
              kstyle(grpPkg, 1, 2) // Group for int
              );

          verifier.assertLambdas(new Lambda(pkg, "MainKt$main$4", 1));
        });
  }

  @Test
  public void testGenericsSignatureInnerEnclosingKs() throws Exception {
    final String mainClassName = "lambdas_kstyle_generics.MainKt";
    runTest(
        "lambdas_kstyle_generics",
        mainClassName,
        KEEP_SIGNATURE_INNER_ENCLOSING,
        getOptionsModifier(),
        app -> {
          if (enableUnusedInterfaceRemoval) {
            // Only test that the code generates the same output as the input code does on the JVM.
            return;
          }

          Verifier verifier = new Verifier(app);
          String pkg = "lambdas_kstyle_generics";
          String grpPkg = allowAccessModification ? "" : pkg;

          verifier.assertLambdaGroups(
              kstyle(grpPkg, 1, 3), // Group for Any
              kstyle(grpPkg, "L", 1), // Group for Beta in First
              kstyle(grpPkg, "L", 1), // Group for Beta in Second
              kstyle(grpPkg, "LS", 1), // Group for Gamma<String> in First
              kstyle(grpPkg, "LS", 1), // Group for Gamma<Integer> in First
              kstyle(grpPkg, "LS", 1), // Group for Gamma<String> in Second
              kstyle(grpPkg, "LS", 1), // Group for Gamma<Integer> in Second
              kstyle(grpPkg, 1, 2) // Group for int
              );

          verifier.assertLambdas(new Lambda(pkg, "MainKt$main$4", 1));
        });
  }

  @Test
  public void testTrivialJs() throws Exception {
    final String mainClassName = "lambdas_jstyle_trivial.MainKt";
    runTest(
        "lambdas_jstyle_trivial",
        mainClassName,
        getOptionsModifier(),
        app -> {
          Verifier verifier = new Verifier(app);
          String pkg = "lambdas_jstyle_trivial";
          String grp = allowAccessModification ? "" : pkg;

          String supplier = "lambdas_jstyle_trivial.Lambdas$Supplier";
          String intSupplier = "lambdas_jstyle_trivial.Lambdas$IntSupplier";
          String consumer = "lambdas_jstyle_trivial.Lambdas$Consumer";
          String intConsumer = "lambdas_jstyle_trivial.Lambdas$IntConsumer";
          String multiFunction = "lambdas_jstyle_trivial.Lambdas$MultiFunction";

          verifier.assertLambdaGroups(
              jstyle(grp, 0, intSupplier, 2),
              jstyle(grp, "L", 0, supplier),
              jstyle(grp, "LL", 0, supplier),
              jstyle(grp, "LLL", 0, supplier),
              jstyle(grp, 1, intConsumer, allowAccessModification ? 3 : 2),
              jstyle(grp, "I", 1, consumer),
              jstyle(grp, "II", 1, consumer),
              jstyle(grp, "III", 1, consumer),
              jstyle(grp, "IIII", 1, consumer),
              jstyle(grp, 3, multiFunction, 2),
              jstyle(grp, 3, multiFunction, 2),
              jstyle(grp, 3, multiFunction, 4),
              jstyle(grp, 3, multiFunction, 6));

          verifier.assertLambdas(
              allowAccessModification
                  ? new Lambda[] {
                    new Lambda(pkg + "/inner", "InnerKt$testInner1$4", 1),
                    new Lambda(pkg + "/inner", "InnerKt$testInner1$5", 1)
                  }
                  : new Lambda[] {
                    new Lambda(pkg + "/inner", "InnerKt$testInner1$1", 1),
                    new Lambda(pkg + "/inner", "InnerKt$testInner1$2", 1),
                    new Lambda(pkg + "/inner", "InnerKt$testInner1$3", 1),
                    new Lambda(pkg + "/inner", "InnerKt$testInner1$4", 1),
                    new Lambda(pkg + "/inner", "InnerKt$testInner1$5", 1)
                  });
        });
  }

  @Test
  public void testSingleton() throws Exception {
    final String mainClassName = "lambdas_singleton.MainKt";
    runTest(
        "lambdas_singleton",
        mainClassName,
        getOptionsModifier(),
        app -> {
          Verifier verifier = new Verifier(app);
          String pkg = "lambdas_singleton";
          String grp = allowAccessModification ? "" : pkg;

          verifier.assertLambdaGroups(
              kstyle(grp, 1, 1 /* 1 out of 5 lambdas in the group */),
              jstyle(grp, 2, "java.util.Comparator", 0 /* 0 out of 2 lambdas in the group */));

          verifier.assertLambdas(/* None */ );
        });
  }
}
