// 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 com.google.devtools.build.lib.testutil.MoreAsserts.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.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");
  }
}
