// Copyright (c) 2020, 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.graph;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
import com.android.tools.r8.graph.GenericSignature.ReturnType;
import com.android.tools.r8.graph.GenericSignature.TypeSignature;
import com.android.tools.r8.graph.GenericSignature.WildcardIndicator;
import com.android.tools.r8.graph.GenericSignatureTestClassA.I;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FieldSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class GenericSignatureTest extends TestBase {

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withNoneRuntime().build();
  }

  public GenericSignatureTest(TestParameters parameters) {}

  @Test
  public void test() throws Exception {
    AndroidApp app =
        testForD8()
            .debug()
            .addProgramClassesAndInnerClasses(
                GenericSignatureTestClassA.class,
                GenericSignatureTestClassB.class,
                GenericSignatureTestClassCY.class,
                GenericSignatureTestClassCYY.class)
            .compile()
            .app;
    AppView<AppInfoWithLiveness> appView = computeAppViewWithLiveness(app);
    DexItemFactory factory = appView.dexItemFactory();
    CodeInspector inspector = new CodeInspector(appView.appInfo().app());

    ClassSubject a = inspector.clazz(GenericSignatureTestClassA.class);
    assertThat(a, isPresent());
    ClassSubject y = inspector.clazz(GenericSignatureTestClassA.Y.class);
    assertThat(y, isPresent());
    ClassSubject yy = inspector.clazz(GenericSignatureTestClassA.Y.YY.class);
    assertThat(yy, isPresent());
    ClassSubject zz = inspector.clazz(GenericSignatureTestClassA.Y.ZZ.class);
    assertThat(zz, isPresent());
    ClassSubject b = inspector.clazz(GenericSignatureTestClassB.class);
    assertThat(b, isPresent());
    ClassSubject cy = inspector.clazz(GenericSignatureTestClassCY.class);
    assertThat(cy, isPresent());
    ClassSubject cyy = inspector.clazz(GenericSignatureTestClassCYY.class);
    assertThat(cyy, isPresent());
    ClassSubject i = inspector.clazz(I.class);
    assertThat(cyy, isPresent());

    DexEncodedMethod method;

    ClassSignature classSignature;
    ClassTypeSignature classTypeSignature;
    FieldTypeSignature fieldTypeSignature;
    MethodTypeSignature methodTypeSignature;
    List<FieldTypeSignature> typeArguments;
    FieldTypeSignature typeArgument;
    TypeSignature parameterSignature;
    TypeSignature elementSignature;
    ReturnType returnType;
    TypeSignature returnTypeSignature;

    //
    // Testing ClassSignature
    //

    // class <T:GenericSignatureTestClassA<T>.Y>CYY<T extends A<T>.Y> extends CY<T>
    DexClass clazz = cyy.getDexProgramClass();
    assertNotNull(clazz);
    classSignature =
        GenericSignature.parseClassSignature(
            clazz.getType().getName(),
            getGenericSignature(clazz, appView),
            clazz.origin,
            appView.dexItemFactory(),
            appView.options().reporter);
    assertNotNull(classSignature);

    assertEquals(1, classSignature.formalTypeParameters.size());
    FormalTypeParameter formalTypeParameter = classSignature.formalTypeParameters.get(0);
    assertEquals("T", formalTypeParameter.name);
    assertNull(formalTypeParameter.interfaceBounds);
    assertTrue(formalTypeParameter.classBound.isClassTypeSignature());
    ClassTypeSignature classBoundSignature = formalTypeParameter.classBound.asClassTypeSignature();
    assertEquals(y.getDexProgramClass().type, classBoundSignature.innerTypeSignature.type);
    assertEquals(1, classBoundSignature.typeArguments.size());
    assertEquals(
        "T", classBoundSignature.typeArguments.get(0).asTypeVariableSignature().typeVariable);

    assertTrue(classSignature.superInterfaceSignatures.isEmpty());
    classTypeSignature = classSignature.superClassSignature;
    assertEquals(cy.getDexProgramClass().type, classTypeSignature.type);
    typeArguments = classTypeSignature.typeArguments;
    assertEquals(1, typeArguments.size());
    typeArgument = typeArguments.get(0);
    assertTrue(typeArgument.isTypeVariableSignature());
    assertEquals("T", typeArgument.asTypeVariableSignature().typeVariable);

    //
    // Testing FieldTypeSignature
    //

    FieldSubject yyInZZ = zz.uniqueFieldWithName("yy");
    assertThat(yyInZZ, isPresent());
    DexEncodedField field = yyInZZ.getField();
    assertNotNull(field);

    fieldTypeSignature =
        GenericSignature.parseFieldTypeSignature(
            field.field.qualifiedName(),
            getGenericSignature(field, appView),
            Origin.unknown(),
            appView.dexItemFactory(),
            appView.options().reporter);
    assertNotNull(fieldTypeSignature);

    // field type: A$Y$YY
    assertTrue(fieldTypeSignature.isClassTypeSignature());
    check_A_Y_YY(a, y, yy, fieldTypeSignature.asClassTypeSignature());

    //
    // Testing MethodTypeSignature
    //

    // A$Y$YY newYY([B<T>)
    MethodSubject newYY = zz.uniqueMethodWithName("newYY");
    assertThat(newYY, isPresent());
    method = newYY.getMethod();
    assertNotNull(method);

    methodTypeSignature =
        GenericSignature.parseMethodSignature(
            method.qualifiedName(),
            getGenericSignature(method, appView),
            Origin.unknown(),
            appView.dexItemFactory(),
            appView.options().reporter);
    assertNotNull(methodTypeSignature);

    assertEquals(1, methodTypeSignature.formalTypeParameters.size());
    FormalTypeParameter methodFormalParameter = methodTypeSignature.formalTypeParameters.get(0);
    assertTrue(methodFormalParameter.classBound.isClassTypeSignature());
    assertEquals(
        y.getDexProgramClass().getType(),
        methodFormalParameter.classBound.asClassTypeSignature().innerTypeSignature.type);
    assertNotNull(methodFormalParameter.interfaceBounds);
    assertEquals(1, methodFormalParameter.interfaceBounds.size());
    FieldTypeSignature interfaceBound = methodFormalParameter.interfaceBounds.get(0);
    assertTrue(interfaceBound.isClassTypeSignature());
    assertEquals(i.getDexProgramClass().getType(), interfaceBound.asClassTypeSignature().type);

    // return type: A$Y$YY
    returnType = methodTypeSignature.returnType();
    assertFalse(returnType.isVoidDescriptor());
    returnTypeSignature = returnType.typeSignature();
    assertTrue(returnTypeSignature.isFieldTypeSignature());
    assertTrue(returnTypeSignature.asFieldTypeSignature().isClassTypeSignature());
    check_A_Y_YY(a, y, yy, returnTypeSignature.asFieldTypeSignature().asClassTypeSignature());

    // type of 1st argument: [B<T>
    assertEquals(1, methodTypeSignature.typeSignatures.size());
    parameterSignature = methodTypeSignature.getParameterTypeSignature(0);
    assertNotNull(parameterSignature);
    assertTrue(parameterSignature.isFieldTypeSignature());
    assertTrue(parameterSignature.asFieldTypeSignature().isArrayTypeSignature());
    elementSignature =
        parameterSignature.asFieldTypeSignature().asArrayTypeSignature().elementSignature;
    assertTrue(elementSignature.isFieldTypeSignature());
    assertTrue(elementSignature.asFieldTypeSignature().isClassTypeSignature());
    classTypeSignature = elementSignature.asFieldTypeSignature().asClassTypeSignature();
    assertEquals(b.getDexProgramClass().type, classTypeSignature.type);

    // Function<A$Y$ZZ<TT>, A$Y$YY> convertToYY(Supplier<A$Y$ZZ<TT>>
    MethodSubject convertToYY = zz.uniqueMethodWithName("convertToYY");
    assertThat(convertToYY, isPresent());
    method = convertToYY.getMethod();
    assertNotNull(method);

    methodTypeSignature =
        GenericSignature.parseMethodSignature(
            method.qualifiedName(),
            getGenericSignature(method, appView),
            Origin.unknown(),
            appView.dexItemFactory(),
            appView.options().reporter);
    assertNotNull(methodTypeSignature);

    // return type: Function<A$Y$ZZ<TT>, A$Y$YY>
    returnType = methodTypeSignature.returnType();
    assertFalse(returnType.isVoidDescriptor());
    returnTypeSignature = returnType.typeSignature();
    assertTrue(returnTypeSignature.isFieldTypeSignature());
    assertTrue(returnTypeSignature.asFieldTypeSignature().isClassTypeSignature());
    classTypeSignature = returnTypeSignature.asFieldTypeSignature().asClassTypeSignature();
    DexType functionType =
        factory.createType(DescriptorUtils.javaTypeToDescriptor(Function.class.getTypeName()));
    assertEquals(functionType, classTypeSignature.type);

    typeArguments = classTypeSignature.typeArguments;
    assertEquals(2, typeArguments.size());

    typeArgument = typeArguments.get(0);
    assertTrue(typeArgument.isClassTypeSignature());
    check_A_Y_ZZ(a, y, zz, typeArgument.asClassTypeSignature());

    typeArgument = typeArguments.get(1);
    assertTrue(typeArgument.isClassTypeSignature());
    check_A_Y_YY(a, y, yy, typeArgument.asClassTypeSignature());

    // type of 1st argument: Supplier<A$Y$ZZ<TT>>
    assertEquals(1, methodTypeSignature.typeSignatures.size());
    parameterSignature = methodTypeSignature.getParameterTypeSignature(0);
    check_supplier(factory, a, y, zz, parameterSignature);

    // void boo(Supplier<A$Y$ZZ<TT>>)
    MethodSubject boo = zz.uniqueMethodWithName("boo");
    assertThat(boo, isPresent());
    method = boo.getMethod();
    assertNotNull(method);

    // return type: void
    methodTypeSignature =
        GenericSignature.parseMethodSignature(
            method.qualifiedName(),
            getGenericSignature(method, appView),
            Origin.unknown(),
            appView.dexItemFactory(),
            appView.options().reporter);
    assertNotNull(methodTypeSignature);
    returnType = methodTypeSignature.returnType();
    assertTrue(returnType.isVoidDescriptor());

    // type of 1st argument: Supplier<A$Y$ZZ<TT>>
    assertEquals(1, methodTypeSignature.typeSignatures.size());
    parameterSignature = methodTypeSignature.getParameterTypeSignature(0);
    check_supplier(factory, a, y, zz, parameterSignature);

    // check_A_Y_foo for star, negative and positive wildcards
    check_A_Y_foo_bar_baz(y, appView);
  }

  private void check_A_Y(ClassSubject a, ClassSubject y, ClassTypeSignature signature) {
    assertEquals(a.getDexProgramClass().type, signature.type);
    List<FieldTypeSignature> typeArguments = signature.typeArguments;
    assertEquals(1, typeArguments.size());
    FieldTypeSignature typeArgument = typeArguments.get(0);
    assertTrue(typeArgument.isTypeVariableSignature());
    assertEquals("T", typeArgument.asTypeVariableSignature().typeVariable);
    assertEquals(y.getDexProgramClass().type, signature.innerTypeSignature.type);
  }

  private void check_A_Y_YY(
      ClassSubject a, ClassSubject y, ClassSubject yy, ClassTypeSignature signature) {
    check_A_Y(a, y, signature);
    assertEquals(
        yy.getDexProgramClass().type, signature.innerTypeSignature.innerTypeSignature.type);
  }

  private void check_A_Y_ZZ(
      ClassSubject a, ClassSubject y, ClassSubject zz, ClassTypeSignature signature) {
    check_A_Y(a, y, signature);
    ClassTypeSignature innerMost = signature.innerTypeSignature.innerTypeSignature;
    assertEquals(zz.getDexProgramClass().type, innerMost.type);
    List<FieldTypeSignature> typeArguments = innerMost.typeArguments;
    assertEquals(1, typeArguments.size());
    FieldTypeSignature typeArgument = typeArguments.get(0);
    assertTrue(typeArgument.isTypeVariableSignature());
    assertEquals("TT", typeArgument.asTypeVariableSignature().typeVariable);
  }

  private void check_A_Y_foo_bar_baz(ClassSubject y, AppView<AppInfoWithLiveness> appView) {
    checkMethodWildCard(y.uniqueMethodWithName("foo"), appView, WildcardIndicator.POSITIVE);
    checkMethodWildCard(y.uniqueMethodWithName("bar"), appView, WildcardIndicator.NEGATIVE);
    // Check for star
    checkFieldTypeSignature(
        y.uniqueMethodWithName("baz"),
        appView,
        typeSignature -> {
          assertTrue(typeSignature.isStar());
        });
  }

  private void checkMethodWildCard(
      MethodSubject methodSubject,
      AppView<AppInfoWithLiveness> appView,
      WildcardIndicator indicator) {
    checkFieldTypeSignature(
        methodSubject,
        appView,
        typeSignature -> {
          assertTrue(typeSignature.isTypeVariableSignature());
          assertEquals(indicator, typeSignature.getWildcardIndicator());
        });
  }

  private void checkFieldTypeSignature(
      MethodSubject methodSubject,
      AppView<AppInfoWithLiveness> appView,
      Consumer<FieldTypeSignature> fieldTypeConsumer) {
    MethodTypeSignature methodTypeSignature =
        GenericSignature.parseMethodSignature(
            methodSubject.getOriginalName(),
            getGenericSignature(methodSubject.getMethod(), appView),
            Origin.unknown(),
            appView.dexItemFactory(),
            appView.options().reporter);
    TypeSignature typeSignature = methodTypeSignature.returnType.typeSignature;
    FieldTypeSignature fieldTypeSignature = typeSignature.asFieldTypeSignature();
    assertTrue(fieldTypeSignature.isClassTypeSignature());
    ClassTypeSignature classTypeSignature = fieldTypeSignature.asClassTypeSignature();
    assertFalse(classTypeSignature.isArgument());
    assertEquals(1, classTypeSignature.typeArguments.size());
    FieldTypeSignature typeArgument = classTypeSignature.typeArguments.get(0);
    fieldTypeConsumer.accept(typeArgument);
  }

  private void check_supplier(
      DexItemFactory factory,
      ClassSubject a,
      ClassSubject y,
      ClassSubject zz,
      TypeSignature signature) {
    assertNotNull(signature);
    assertTrue(signature.isFieldTypeSignature());
    assertTrue(signature.asFieldTypeSignature().isClassTypeSignature());
    ClassTypeSignature classTypeSignature = signature.asFieldTypeSignature().asClassTypeSignature();
    DexType supplierType =
        factory.createType(DescriptorUtils.javaTypeToDescriptor(Supplier.class.getTypeName()));
    assertEquals(supplierType, classTypeSignature.type);
    List<FieldTypeSignature> typeArguments = classTypeSignature.typeArguments;
    assertEquals(1, typeArguments.size());
    FieldTypeSignature typeArgument = typeArguments.get(0);
    assertTrue(typeArgument.isClassTypeSignature());
    check_A_Y_ZZ(a, y, zz, typeArgument.asClassTypeSignature());
  }

  private static String getGenericSignature(
      DexDefinition definition, AppView<AppInfoWithLiveness> appView) {
    DexAnnotationSet annotations = definition.annotations();
    if (annotations.annotations.length == 0) {
      return null;
    }
    for (int i = 0; i < annotations.annotations.length; i++) {
      DexAnnotation annotation = annotations.annotations[i];
      if (!DexAnnotation.isSignatureAnnotation(annotation, appView.dexItemFactory())) {
        continue;
      }
      return DexAnnotation.getSignature(annotation);
    }
    return null;
  }
}

//
// TODO(b/129925954): Once unified, these would be stale comments.
// Borrowed from ...naming.signature.GenericSignatureRenamingTest
// and then extended a bit to explore more details, e.g., MethodTypeSignature.
//

class GenericSignatureTestClassA<T> {

  interface I {}

  class Y {

    class YY {}

    class ZZ<TT> extends YY {
      public YY yy;

      <R extends Y & I> YY newYY(GenericSignatureTestClassB... bs) {
        return new YY();
      }

      Function<ZZ<TT>, YY> convertToYY(Supplier<ZZ<TT>> zzSupplier) {
        return zz -> {
          if (System.currentTimeMillis() > 0) {
            return zzSupplier.get().newYY();
          } else {
            return zz.newYY();
          }
        };
      }

      void boo(Supplier<ZZ<TT>> zzSupplier) {
        convertToYY(zzSupplier).apply(this);
      }
    }

    ZZ<T> zz() {
      return new ZZ<T>();
    }

    List<? extends T> foo() {
      return null;
    }

    List<? super T> bar() {
      return null;
    }

    List<?> baz() {
      return null;
    }
  }

  class Z extends Y {}

  static class S {}

  Y newY() {
    return new Y();
  }

  Z newZ() {
    return new Z();
  }

  Y.ZZ<T> newZZ() {
    return new Y().zz();
  }
}

class GenericSignatureTestClassB<T extends GenericSignatureTestClassA<T>> {}

class GenericSignatureTestClassCY<T extends GenericSignatureTestClassA<T>.Y> {}

class GenericSignatureTestClassCYY<T extends GenericSignatureTestClassA<T>.Y>
    extends GenericSignatureTestClassCY<T> {}
