// Copyright 2017 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 org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.android.desugar.testdata.java8.AnnotationsOfDefaultMethodsShouldBeKept.AnnotatedInterface;
import com.google.devtools.build.android.desugar.testdata.java8.AnnotationsOfDefaultMethodsShouldBeKept.SomeAnnotation;
import com.google.devtools.build.android.desugar.testdata.java8.ConcreteDefaultInterfaceWithLambda;
import com.google.devtools.build.android.desugar.testdata.java8.ConcreteOverridesDefaultWithLambda;
import com.google.devtools.build.android.desugar.testdata.java8.DefaultInterfaceMethodWithStaticInitializer;
import com.google.devtools.build.android.desugar.testdata.java8.DefaultInterfaceWithBridges;
import com.google.devtools.build.android.desugar.testdata.java8.DefaultMethodFromSeparateJava8Target;
import com.google.devtools.build.android.desugar.testdata.java8.DefaultMethodFromSeparateJava8TargetOverridden;
import com.google.devtools.build.android.desugar.testdata.java8.DefaultMethodTransitivelyFromSeparateJava8Target;
import com.google.devtools.build.android.desugar.testdata.java8.FunctionWithDefaultMethod;
import com.google.devtools.build.android.desugar.testdata.java8.FunctionalInterfaceWithInitializerAndDefaultMethods;
import com.google.devtools.build.android.desugar.testdata.java8.GenericDefaultInterfaceWithLambda;
import com.google.devtools.build.android.desugar.testdata.java8.InterfaceMethod;
import com.google.devtools.build.android.desugar.testdata.java8.InterfaceWithDefaultMethod;
import com.google.devtools.build.android.desugar.testdata.java8.InterfaceWithDuplicateMethods.ClassWithDuplicateMethods;
import com.google.devtools.build.android.desugar.testdata.java8.InterfaceWithInheritedMethods;
import com.google.devtools.build.android.desugar.testdata.java8.Java7InterfaceWithBridges;
import com.google.devtools.build.android.desugar.testdata.java8.Named;
import com.google.devtools.build.android.desugar.testdata.java8.TwoInheritedDefaultMethods;
import com.google.devtools.build.android.desugar.testdata.java8.VisibilityTestClass;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test that exercises classes in the {@code testdata_java8} 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 DesugarJava8FunctionalTest extends DesugarFunctionalTest {

  public DesugarJava8FunctionalTest() {
    this(true, true);
  }

  protected DesugarJava8FunctionalTest(
      boolean expectBridgesFromSeparateTarget, boolean expectDefaultMethods) {
    super(expectBridgesFromSeparateTarget, expectDefaultMethods);
  }

  @Test
  public void testLambdaInDefaultMethod() {
    assertThat(new ConcreteDefaultInterfaceWithLambda().defaultWithLambda())
        .containsExactly("0", "1")
        .inOrder();
  }

  @Test
  public void testLambdaInDefaultCallsInterfaceMethod() {
    assertThat(new ConcreteDefaultInterfaceWithLambda().defaultCallsInterfaceMethod())
        .containsExactly("1", "2")
        .inOrder();
  }

  @Test
  public void testOverrideLambdaInDefault() {
    assertThat(new ConcreteOverridesDefaultWithLambda().defaultWithLambda())
        .containsExactly("2", "3")
        .inOrder();
  }

  @Test
  public void testLambdaInDefaultCallsOverrideMethod() {
    assertThat(new ConcreteOverridesDefaultWithLambda().defaultCallsInterfaceMethod())
        .containsExactly("3", "4")
        .inOrder();
  }

  @Test
  public void testDefaultInterfaceMethodReference() {
    InterfaceMethod methodrefUse = new InterfaceMethod.Concrete();
    List<String> dest =
        methodrefUse.defaultMethodReference(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(dest).containsExactly("Sergey");
  }

  @Test
  public void testStaticInterfaceMethodReference() {
    InterfaceMethod methodrefUse = new InterfaceMethod.Concrete();
    List<String> dest =
        methodrefUse.staticMethodReference(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(dest).containsExactly("Alex");
  }

  @Test
  public void testLambdaCallsDefaultMethod() {
    InterfaceMethod methodrefUse = new InterfaceMethod.Concrete();
    List<String> dest =
        methodrefUse.lambdaCallsDefaultMethod(ImmutableList.of("Sergey", "Larry", "Alex"));
    assertThat(dest).containsExactly("Sergey");
  }

  @Test
  public void testBootclasspathMethodInvocations() {
    InterfaceMethod concrete = new InterfaceMethod.Concrete();
    assertThat(concrete.defaultInvokingBootclasspathMethods("Larry")).isEqualTo("Larry");
  }

  @Test
  public void testStaticMethodsInInterface_explicitAndLambdaBody() {
    List<Long> result = FunctionWithDefaultMethod.DoubleInts.add(ImmutableList.of(7, 39, 8), 3);
    assertThat(result).containsExactly(10L, 42L, 11L).inOrder();
  }

  @Test
  public void testOverriddenDefaultMethod_inHandwrittenClass() {
    FunctionWithDefaultMethod<Integer> doubler = new FunctionWithDefaultMethod.DoubleInts();
    assertThat(doubler.apply(7)).isEqualTo(14);
    assertThat(doubler.twice(7)).isEqualTo(35);
  }

  @Test
  public void testOverriddenDefaultMethod_inHandwrittenSuperclass() {
    FunctionWithDefaultMethod<Integer> doubler = new FunctionWithDefaultMethod.DoubleInts2();
    assertThat(doubler.apply(7)).isEqualTo(14);
    assertThat(doubler.twice(7)).isEqualTo(35);
  }

  @Test
  public void testInheritedDefaultMethod_inLambda() {
    FunctionWithDefaultMethod<Integer> doubler =
        FunctionWithDefaultMethod.DoubleInts.doubleLambda();
    assertThat(doubler.apply(7)).isEqualTo(14);
    assertThat(doubler.twice(7)).isEqualTo(28);
  }

  @Test
  public void testDefaultMethodReference_onLambda() {
    FunctionWithDefaultMethod<Integer> plus6 = FunctionWithDefaultMethod.DoubleInts.incTwice(3);
    assertThat(plus6.apply(18)).isEqualTo(24);
    assertThat(plus6.twice(18)).isEqualTo(30);
  }

  @Test
  public void testDefaultMethodReference_onHandwrittenClass() {
    FunctionWithDefaultMethod<Integer> times5 = FunctionWithDefaultMethod.DoubleInts.times5();
    assertThat(times5.apply(6)).isEqualTo(30);
    assertThat(times5.twice(6)).isEqualTo(150); // Irrelevant that DoubleInts overrides twice()
  }

  @Test
  public void testStaticInterfaceMethodReferenceReturned() {
    Function<Integer, FunctionWithDefaultMethod<Integer>> factory =
        FunctionWithDefaultMethod.DoubleInts.incFactory();
    assertThat(factory.apply(6).apply(7)).isEqualTo(13);
    assertThat(factory.apply(6).twice(7)).isEqualTo(19);
  }

  @Test
  public void testSuperDefaultMethodInvocation() {
    assertThat(new TwoInheritedDefaultMethods().name()).isEqualTo("One:Two");
    assertThat(new Named.DefaultName().name()).isEqualTo("DefaultName-once");
    assertThat(new Named.DefaultNameSubclass().name()).isEqualTo("DefaultNameSubclass-once-twice");
  }

  @Test
  public void testInheritedPreferredOverDefault() throws Exception {
    assertThat(new Named.ExplicitName("hello").name()).isEqualTo("hello");
    // Make sure AbstractName remains abstract, despite default method from implemented interface
    assertThat(Modifier.isAbstract(Named.AbstractName.class.getMethod("name").getModifiers()))
        .isTrue();
  }

  @Test
  public void testRedefinedDefaultMethod() throws Exception {
    assertThat(new InterfaceWithDefaultMethod.Version2().version()).isEqualTo(2);
  }

  @Test
  public void testDefaultMethodRedefinedInSubclass() throws Exception {
    assertThat(new InterfaceWithDefaultMethod.AlsoVersion2().version()).isEqualTo(2);
  }

  @Test
  public void testDefaultMethodVisibility() {
    assertThat(new VisibilityTestClass().m()).isEqualTo(42);
  }

  /** Test for b/38302860 */
  @Test
  public void testAnnotationsOfDefaultMethodsAreKept() throws Exception {
    {
      Annotation[] annotations = AnnotatedInterface.class.getAnnotations();
      assertThat(annotations).hasLength(1);
      assertThat(annotations[0]).isInstanceOf(SomeAnnotation.class);
      assertThat(((SomeAnnotation) annotations[0]).value()).isEqualTo(1);
    }
    {
      Annotation[] annotations =
          AnnotatedInterface.class.getMethod("annotatedAbstractMethod").getAnnotations();
      assertThat(annotations).hasLength(1);
      assertThat(annotations[0]).isInstanceOf(SomeAnnotation.class);
      assertThat(((SomeAnnotation) annotations[0]).value()).isEqualTo(2);
    }
    {
      Annotation[] annotations =
          AnnotatedInterface.class.getMethod("annotatedDefaultMethod").getAnnotations();
      assertThat(annotations).hasLength(1);
      assertThat(annotations[0]).isInstanceOf(SomeAnnotation.class);
      assertThat(((SomeAnnotation) annotations[0]).value()).isEqualTo(3);
    }
  }
  /** Test for b/38308515 */
  @Test
  public void testDefaultAndStaticMethodNameClash() {
    final ClassWithDuplicateMethods instance = new ClassWithDuplicateMethods();
    assertThat(instance.getZero()).isEqualTo(0);
    assertThat(instance.getZeroFromStaticInterfaceMethod()).isEqualTo(1);
  }

  /**
   * Test for b/38257037
   *
   * <p>Note that, we intentionally suppress unchecked warnings, because we expect some
   * ClassCastException to test bridge methods.
   */
  @SuppressWarnings("unchecked")
  @Test
  public void testBridgeAndDefaultMethods() {
    {
      DefaultInterfaceWithBridges object = new DefaultInterfaceWithBridges();
      Integer one = 1;
      assertThat(object.copy(one)).isEqualTo(one);
      assertThat(object.copy((Number) one)).isEqualTo(one);
      assertThrows(ClassCastException.class, () -> object.copy(Double.valueOf(1)));

      assertThat(object.getNumber()).isInstanceOf(Double.class);
      assertThat(object.getNumber()).isEqualTo(Double.valueOf(2.3d));
      assertThat(object.getDouble()).isEqualTo(Double.valueOf(2.3d));
    }
    {
      Java7InterfaceWithBridges.ClassAddTwo testObject =
          new Java7InterfaceWithBridges.ClassAddTwo();
      assertThat(testObject.add(Integer.valueOf(2))).isEqualTo(4);

      @SuppressWarnings("rawtypes")
      Java7InterfaceWithBridges top = testObject;
      assertThat(top.add(Integer.valueOf(2))).isEqualTo(4);
      assertThrows(ClassCastException.class, () -> top.add(new Object()));
      assertThrows(ClassCastException.class, () -> top.add(Double.valueOf(1)));
      assertThrows(ClassCastException.class, () -> top.add(Long.valueOf(1)));

      @SuppressWarnings("rawtypes")
      Java7InterfaceWithBridges.LevelOne levelOne = testObject;
      assertThat(levelOne.add(Integer.valueOf(2))).isEqualTo(4);
      assertThrows(ClassCastException.class, () -> top.add(new Object()));
      assertThrows(ClassCastException.class, () -> top.add(Double.valueOf(1)));
      assertThrows(ClassCastException.class, () -> top.add(Long.valueOf(1)));

      @SuppressWarnings("rawtypes")
      Java7InterfaceWithBridges.LevelOne levelTwo = testObject;
      assertThat(levelTwo.add(Integer.valueOf(2))).isEqualTo(4);
      assertThrows(ClassCastException.class, () -> levelTwo.add(Double.valueOf(1)));
      assertThrows(ClassCastException.class, () -> levelTwo.add(Long.valueOf(1)));
    }
    {
      GenericDefaultInterfaceWithLambda.ClassTwo testObject =
          new GenericDefaultInterfaceWithLambda.ClassTwo();

      assertThat(testObject.increment(Integer.valueOf(0))).isEqualTo(1);
      assertThat(testObject.toString(Integer.valueOf(0))).isEqualTo("0");
      assertThat(testObject.getBaseValue()).isEqualTo(Integer.valueOf(0));

      assertThat(testObject.toList(0)).isEmpty();
      assertThat(testObject.toList(1)).containsExactly(0).inOrder();
      assertThat(testObject.toList(2)).containsExactly(0, 1).inOrder();

      assertThat(((Function<Integer, ArrayList<Integer>>) testObject.toListSupplier()).apply(0))
          .isEmpty();
      assertThat(((Function<Integer, ArrayList<Integer>>) testObject.toListSupplier()).apply(1))
          .containsExactly(0)
          .inOrder();
      assertThat(((Function<Integer, ArrayList<Integer>>) testObject.toListSupplier()).apply(2))
          .containsExactly(0, 1)
          .inOrder();

      assertThat(testObject.convertToStringList(ImmutableList.of(0)))
          .containsExactly("0")
          .inOrder();
      assertThat(testObject.convertToStringList(ImmutableList.of(0, 1)))
          .containsExactly("0", "1")
          .inOrder();

      @SuppressWarnings("rawtypes")
      GenericDefaultInterfaceWithLambda top = testObject;
      assertThrows(ClassCastException.class, () -> top.increment(Long.valueOf(1)));
      assertThrows(ClassCastException.class, () -> top.toString(Long.valueOf(1)));
      assertThat(top.increment(Integer.valueOf(0))).isEqualTo(1);
      assertThat(top.toString(Integer.valueOf(0))).isEqualTo("0");
      assertThat(top.getBaseValue()).isEqualTo(Integer.valueOf(0));

      assertThat(top.toList(0)).isEmpty();
      assertThat(top.toList(1)).containsExactly(0).inOrder();
      assertThat(top.toList(2)).containsExactly(0, 1).inOrder();

      assertThat(((Function<Integer, ArrayList<Integer>>) top.toListSupplier()).apply(0)).isEmpty();
      assertThat(((Function<Integer, ArrayList<Integer>>) top.toListSupplier()).apply(1))
          .containsExactly(0)
          .inOrder();
      assertThat(((Function<Integer, ArrayList<Integer>>) top.toListSupplier()).apply(2))
          .containsExactly(0, 1)
          .inOrder();

      assertThat(top.convertToStringList(ImmutableList.of(0))).containsExactly("0").inOrder();
      assertThat(top.convertToStringList(ImmutableList.of(0, 1)))
          .containsExactly("0", "1")
          .inOrder();
    }
    {
      @SuppressWarnings("rawtypes")
      GenericDefaultInterfaceWithLambda testObject =
          new GenericDefaultInterfaceWithLambda.ClassThree();
      assertThat(testObject.getBaseValue()).isEqualTo(Long.valueOf(0));
      assertThat(testObject.increment(Long.valueOf(0))).isEqualTo(Long.valueOf(0 + 1));
      assertThat(testObject.toString(Long.valueOf(0))).isEqualTo(Long.valueOf(0).toString());
      assertThrows(ClassCastException.class, () -> testObject.increment(Integer.valueOf(0)));
      assertThrows(ClassCastException.class, () -> testObject.toString(Integer.valueOf(0)));
      assertThat(testObject.toList(2)).containsExactly(Long.valueOf(0), Long.valueOf(1)).inOrder();
      assertThat(testObject.convertToStringList(testObject.toList(1))).containsExactly("0");
      assertThat(((Function<Integer, ArrayList<Long>>) testObject.toListSupplier()).apply(2))
          .containsExactly(Long.valueOf(0), Long.valueOf(1));
    }
  }

  /**
   * Test for b/62047432.
   *
   * <p>When desugaring a functional interface with an executable clinit and default methods, we
   * erase the body of clinit to avoid executing it during desugaring. This test makes sure that all
   * the constants defined in the interface are still there after desugaring.
   */
  @Test
  public void testFunctionalInterfaceWithExecutableClinitStillWorkAfterDesugar() {
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.CONSTANT.length("").convert())
        .isEqualTo(0);
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.CONSTANT.length("1").convert())
        .isEqualTo(1);
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.BOOLEAN).isFalse();
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.CHAR).isEqualTo('h');
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.BYTE).isEqualTo(0);
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.SHORT).isEqualTo(0);

    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.INT).isEqualTo(0);
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.FLOAT).isEqualTo(0f);
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.LONG).isEqualTo(0);
    assertThat(FunctionalInterfaceWithInitializerAndDefaultMethods.DOUBLE).isEqualTo(0d);
  }

  /** Test for b/38255926. */
  @Test
  public void testDefaultMethodInitializationOrder() {
    {
      assertThat(new DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetOne.C().sum())
          .isEqualTo(11); // To trigger loading the class C and its super interfaces.
      assertThat(
              DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetOne
                  .getRealInitializationOrder())
          .isEqualTo(
              DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetOne
                  .getExpectedInitializationOrder());
    }
    {
      assertThat(new DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetTwo.C().sum())
          .isEqualTo(3);
      assertThat(
              DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetTwo
                  .getRealInitializationOrder())
          .isEqualTo(
              DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetTwo
                  .getExpectedInitializationOrder());
    }
    {
      assertThat(new DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetThree.C().sum())
          .isEqualTo(11);
      assertThat(
              DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetThree
                  .getRealInitializationOrder())
          .isEqualTo(
              DefaultInterfaceMethodWithStaticInitializer.TestInterfaceSetThree
                  .getExpectedInitializationOrder());
    }
  }

  /**
   * Tests that default methods on the classpath are correctly handled. We'll also verify the
   * metadata that's emitted for this case to make sure the binary-wide double-check for correct
   * desugaring of default and static interface methods keeps working (b/65645388).
   */
  @Test
  public void testDefaultMethodsInSeparateTarget() {
    assertThat(new DefaultMethodFromSeparateJava8Target().dflt()).isEqualTo("dflt");
    assertThat(new DefaultMethodTransitivelyFromSeparateJava8Target().dflt()).isEqualTo("dflt");
    assertThat(new DefaultMethodFromSeparateJava8TargetOverridden().dflt()).isEqualTo("override");
  }

  /** Regression test for b/73355452 */
  @Test
  public void testSuperCallToInheritedDefaultMethod() {
    assertThat(new InterfaceWithInheritedMethods.Impl().name()).isEqualTo("Base");
    assertThat(new InterfaceWithInheritedMethods.Impl().suffix()).isEqualTo("!");
  }
}
