// Copyright 2016 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.android.desugar;

import static com.google.common.truth.Truth.assertThat;
import static java.lang.reflect.Modifier.isFinal;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import com.google.devtools.build.android.desugar.testdata.CaptureLambda;
import com.google.devtools.build.android.desugar.testdata.ConcreteFunction;
import com.google.devtools.build.android.desugar.testdata.ConstructorReference;
import com.google.devtools.build.android.desugar.testdata.GuavaLambda;
import com.google.devtools.build.android.desugar.testdata.InnerClassLambda;
import com.google.devtools.build.android.desugar.testdata.InterfaceWithLambda;
import com.google.devtools.build.android.desugar.testdata.Lambda;
import com.google.devtools.build.android.desugar.testdata.LambdaInOverride;
import com.google.devtools.build.android.desugar.testdata.MethodReference;
import com.google.devtools.build.android.desugar.testdata.MethodReferenceInSubclass;
import com.google.devtools.build.android.desugar.testdata.MethodReferenceSuperclass;
import com.google.devtools.build.android.desugar.testdata.OuterReferenceLambda;
import com.google.devtools.build.android.desugar.testdata.SpecializedFunction;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test that exercises classes in the {@code testdata} package.  This is meant to be run against a
 * desugared version of those classes, which in turn exercise various desugaring features.
 */
@RunWith(JUnit4.class)
public class DesugarFunctionalTest {

  private final int expectedBridgesFromSameTarget;
  private final int expectedBridgesFromSeparateTarget;
  private final boolean expectLambdaMethodsInInterfaces;

  public DesugarFunctionalTest() {
    this(3, 1, false);
  }

  /** Constructor for testing desugar while allowing default and static interface methods. */
  protected DesugarFunctionalTest(
      boolean expectBridgesFromSeparateTarget, boolean expectDefaultMethods) {
    this(
        expectDefaultMethods ? 0 : 3,
        expectBridgesFromSeparateTarget ? 1 : 0,
        expectDefaultMethods);
  }

  private DesugarFunctionalTest(int bridgesFromSameTarget, int bridgesFromSeparateTarget,
      boolean lambdaMethodsInInterfaces) {
    this.expectedBridgesFromSameTarget = bridgesFromSameTarget;
    this.expectedBridgesFromSeparateTarget = bridgesFromSeparateTarget;
    this.expectLambdaMethodsInInterfaces = lambdaMethodsInInterfaces;
  }

  @Test
  public void testGuavaLambda() {
    GuavaLambda lambdaUse = new GuavaLambda(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(lambdaUse.as()).containsExactly("Alex");
  }

  @Test
  public void testJavaLambda() {
    Lambda lambdaUse = new Lambda(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(lambdaUse.as()).containsExactly("Alex");
  }

  @Test
  public void testLambdaForIntersectionType() throws Exception {
    assertThat(Lambda.hello().call()).isEqualTo("hello");
  }

  @Test
  public void testCapturingLambda() {
    CaptureLambda lambdaUse = new CaptureLambda(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(lambdaUse.prefixed("L")).containsExactly("Larry");
  }

  @Test
  public void testOuterReferenceLambda() throws Exception {
    OuterReferenceLambda lambdaUse = new OuterReferenceLambda(ImmutableList.of("Sergey", "Larry"));
    assertThat(lambdaUse.filter(ImmutableList.of("Larry", "Alex"))).containsExactly("Larry");
    assertThat(
        isFinal(
            OuterReferenceLambda.class
                .getDeclaredMethod("lambda$filter$0$OuterReferenceLambda", String.class)
                .getModifiers()))
        .isTrue();
  }

  /**
   * Tests a lambda in a subclass whose generated lambda$ method has the same name and signature
   * as a lambda$ method generated by Javac in a superclass and both of these methods are used
   * in the implementation of the subclass (by calling super).  Naively this leads to wrong
   * behavior (in this case, return a non-empty list) because the lambda$ in the superclass is never
   * used once its made non-private during desugaring.
   */
  @Test
  public void testOuterReferenceLambdaInOverride() throws Exception {
    OuterReferenceLambda lambdaUse = new LambdaInOverride(ImmutableList.of("Sergey", "Larry"));
    assertThat(lambdaUse.filter(ImmutableList.of("Larry", "Alex"))).isEmpty();
    assertThat(
        isFinal(
            LambdaInOverride.class
                .getDeclaredMethod("lambda$filter$0$LambdaInOverride", String.class)
                .getModifiers()))
        .isTrue();
  }

  @Test
  public void testLambdaInAnonymousClassReferencesSurroundingMethodParameter() throws Exception {
    assertThat(Lambda.mult(21).apply(2).call()).isEqualTo(42);
  }

  /** Tests a lambda that accesses a method parameter across 2 nested anonymous classes. */
  @Test
  public void testLambdaInNestedAnonymousClass() throws Exception {
    InnerClassLambda lambdaUse = new InnerClassLambda(ImmutableList.of("Sergey", "Larry"));
    assertThat(lambdaUse.prefixFilter("L").apply(ImmutableList.of("Lois", "Larry")).call())
        .containsExactly("Larry");
  }

  @Test
  public void testClassMethodReference() {
    MethodReference methodrefUse = new MethodReference(ImmutableList.of("Sergey", "Larry", "Alex"));
    StringBuilder dest = new StringBuilder();
    methodrefUse.appendAll(dest);
    assertThat(dest.toString()).isEqualTo("SergeyLarryAlex");
  }

  // Regression test for b/33378312
  @Test
  public void testHiddenMethodReference() {
    MethodReference methodrefUse = new MethodReference(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(methodrefUse.intersect(ImmutableList.of("Alex", "Sundar"))).containsExactly("Alex");
  }

  // Regression test for b/33378312
  @Test
  public void testHiddenStaticMethodReference() {
    MethodReference methodrefUse =
        new MethodReference(ImmutableList.of("Sergey", "Larry", "Sundar"));
    assertThat(methodrefUse.some()).containsExactly("Sergey", "Sundar");
  }

  @Test
  public void testDuplicateHiddenMethodReference() {
    MethodReference methodrefUse = new MethodReference(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(methodrefUse.onlyIn(ImmutableList.of("Alex", "Sundar"))).containsExactly("Sundar");
  }

  // Regression test for b/36201257
  @Test
  public void testMethodReferenceThatNeedsBridgeInSubclass() {
    MethodReferenceInSubclass methodrefUse =
        new MethodReferenceInSubclass(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(methodrefUse.containsE()).containsExactly("Sergey", "Alex");
    assertThat(methodrefUse.startsWithL()).containsExactly("Larry");
    // Test sanity: make sure sub- and superclass have bridge methods with matching descriptors but
    // different names
    Method superclassBridge = findOnlyBridge(MethodReferenceSuperclass.class);
    Method subclassBridge = findOnlyBridge(MethodReferenceInSubclass.class);
    assertThat(superclassBridge.getName()).isNotEqualTo(subclassBridge.getName());
    assertThat(superclassBridge.getParameterTypes()).isEqualTo(subclassBridge.getParameterTypes());
  }

  private Method findOnlyBridge(Class<?> clazz) {
    Method result = null;
    for (Method m : clazz.getDeclaredMethods()) {
      if (m.getName().startsWith("bridge$")) {
        assertThat(result).named(m.getName()).isNull();
        result = m;
      }
    }
    assertThat(result).named(clazz.getSimpleName()).isNotNull();
    return result;
  }

  // Regression test for b/33378312
  @Test
  public void testThrowingPrivateMethodReference() throws Exception {
    MethodReference methodrefUse = new MethodReference(ImmutableList.of("Sergey", "Larry"));
    Callable<?> stringer = methodrefUse.stringer();
    try {
      stringer.call();
      fail("IOException expected");
    } catch (IOException expected) {
      assertThat(expected).hasMessage("SergeyLarry");
    } catch (Exception e) {
      throw e;
    }
  }

  // Regression test for b/33304582
  @Test
  public void testInterfaceMethodReference() {
    MethodReference methodrefUse = new MethodReference(ImmutableList.of("Sergey", "Larry", "Alex"));
    MethodReference.Transformer<String> transform = new MethodReference.Transformer<String>() {
      @Override
      public String transform(String input) {
        return input.substring(1);
      }
    };
    assertThat(methodrefUse.transform(transform)).containsExactly("ergey", "arry", "lex");
  }

  @Test
  public void testConstructorReference() {
    ConstructorReference initRefUse = new ConstructorReference(ImmutableList.of("1", "2", "42"));
    assertThat(initRefUse.toInt()).containsExactly(1, 2, 42);
  }

  // Regression test for b/33304582
  @Test
  public void testPrivateConstructorReference() {
    ConstructorReference initRefUse = ConstructorReference.singleton().apply("17");
    assertThat(initRefUse.toInt()).containsExactly(17);
  }

  // This test is similar to testPrivateConstructorReference but the private constructor of an inner
  // class is used as a method reference.  That causes Javac to generate a bridge constructor and
  // a lambda body method that calls it, so the desugaring step doesn't need to do anything to make
  // the private constructor visible.  This is mostly to double-check that we don't interfere with
  // this "already-working" scenario.
  @Test
  public void testPrivateConstructorAccessedThroughJavacGeneratedBridge() {
    try {
      @SuppressWarnings("unused") // local is needed to make ErrorProne happy
      ConstructorReference unused = ConstructorReference.emptyThroughJavacGeneratedBridge().get();
      fail("RuntimeException expected");
    } catch (RuntimeException expected) {
      assertThat(expected).hasMessage("got it!");
    }
  }

  @Test
  public void testExpressionMethodReference() {
    assertThat(
            MethodReference.stringChars(new StringBuilder().append("Larry").append("Sergey"))
                .apply(5))
        .isEqualTo('S');
  }

  @Test
  public void testFieldMethodReference() {
    MethodReference methodrefUse = new MethodReference(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(methodrefUse.toPredicate().test("Larry")).isTrue();
    assertThat(methodrefUse.toPredicate().test("Sundar")).isFalse();
  }

  @Test
  public void testConcreteFunctionWithInheritedBridgeMethods() {
    assertThat(new ConcreteFunction().apply("1234567890987654321")).isEqualTo(1234567890987654321L);
    assertThat(ConcreteFunction.parseAll(ImmutableList.of("5", "17"), new ConcreteFunction()))
        .containsExactly(5L, 17L);
  }

  @Test
  public void testLambdaWithInheritedBridgeMethods() throws Exception {
    assertThat(ConcreteFunction.toInt().apply("123456789")).isEqualTo(123456789);
    assertThat(ConcreteFunction.parseAll(ImmutableList.of("5", "17"), ConcreteFunction.toInt()))
        .containsExactly(5, 17);
    // Expect String apply(Number) and any expected bridges
    assertThat(ConcreteFunction.toInt().getClass().getDeclaredMethods())
        .hasLength(expectedBridgesFromSameTarget + 1);
    // Sanity check that we only copied over methods, no fields, from the functional interface
    try {
      ConcreteFunction.toInt().getClass().getDeclaredField("DO_NOT_COPY_INTO_LAMBDA_CLASSES");
      fail("NoSuchFieldException expected");
    } catch (NoSuchFieldException expected) {}
    assertThat(SpecializedFunction.class.getDeclaredField("DO_NOT_COPY_INTO_LAMBDA_CLASSES"))
        .isNotNull(); // test sanity
  }

  /** Tests lambdas with bridge methods when the implemented interface is in a separate target.*/
  @Test
  public void testLambdaWithBridgeMethodsForInterfaceInSeparateTarget() {
    assertThat(ConcreteFunction.isInt().test(123456789L)).isTrue();
    assertThat(
        ConcreteFunction.doFilter(
            ImmutableList.of(123456789L, 1234567890987654321L),
            ConcreteFunction.isInt()))
        .containsExactly(123456789L);
    // Expect test(Number) and any expected bridges
    assertThat(ConcreteFunction.isInt().getClass().getDeclaredMethods())
        .hasLength(expectedBridgesFromSeparateTarget + 1);
  }

  @Test
  public void testLambdaInInterfaceStaticInitializer() {
    assertThat(InterfaceWithLambda.DIGITS).containsExactly("0", "1").inOrder();
    // <clinit> doesn't count but if there's a lambda method then Jacoco adds more methods
    assertThat(InterfaceWithLambda.class.getDeclaredMethods().length != 0)
        .isEqualTo(expectLambdaMethodsInInterfaces);
  }

  /**
   * Sanity-checks that the resource file included in the original Jar is still there unchanged.
   */
  @Test
  public void testResourcePreserved() throws Exception {
    try (InputStream content = Lambda.class.getResource("testresource.txt").openStream()) {
      assertThat(new String(ByteStreams.toByteArray(content), UTF_8)).isEqualTo("test");
    }
  }

  /**
   * Test for b/62456849. After desugar, the method {@code lambda$mult$0} should still be in the
   * class.
   */
  @Test
  public void testCallMethodWithLambdaNamingConvention()
      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    Method method = Lambda.class.getDeclaredMethod("lambda$mult$0");
    Object value = method.invoke(null);
    assertThat(value).isInstanceOf(Integer.class);
    assertThat((Integer) value).isEqualTo(0);
  }
}
