// Copyright (c) 2019, 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.naming.b124357885;

import static com.android.tools.r8.utils.codeinspector.Matchers.isNotRenamed;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.graph.DexAnnotationElement;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.AnnotationSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class B124357885Test extends TestBase {
  public final boolean minification;

  @Parameterized.Parameters(name = "Minification: {0}")
  public static Boolean[] data() {
    return BooleanUtils.values();
  }

  public B124357885Test(boolean minification) {
    this.minification = minification;
  }

  private void checkSignatureAnnotation(CodeInspector inspector, AnnotationSubject signature) {
    DexAnnotationElement[] elements = signature.getAnnotation().elements;
    assertEquals(1, elements.length);
    assertEquals("value", elements[0].name.toString());
    assertTrue(elements[0].value instanceof DexValueArray);
    DexValueArray array = (DexValueArray) elements[0].value;
    StringBuilder builder = new StringBuilder();
    for (DexValue value : array.getValues()) {
      assertTrue(value instanceof DexValueString);
      builder.append(((DexValueString) value).value);
    }
    String fooImplFinalDescriptor =
        DescriptorUtils.javaTypeToDescriptor(inspector.clazz(FooImpl.class).getFinalName());
    StringBuilder expected =
        new StringBuilder()
            .append("()")
            // Remove the final ; from the descriptor to add the generic type.
            .append(fooImplFinalDescriptor.substring(0, fooImplFinalDescriptor.length() - 1))
            .append("<Ljava/lang/String;>")
            // Add the ; after the generic type.
            .append(";");
    assertEquals(expected.toString(), builder.toString());
  }

  @Test
  public void test() throws Exception {
    R8TestCompileResult compileResult = testForR8(Backend.DEX)
        .addProgramClasses(Main.class, Service.class, Foo.class, FooImpl.class)
        .addKeepMainRule(Main.class)
        .addKeepRules("-keepattributes Signature,InnerClasses,EnclosingMethod")
        .minification(minification)
        .compile()
        .inspect(inspector -> {
          assertThat(inspector.clazz(Main.class), isNotRenamed());
          assertThat(inspector.clazz(Service.class), isRenamed(minification));
          assertThat(inspector.clazz(Foo.class), not(isPresent()));
          assertThat(inspector.clazz(FooImpl.class), isRenamed(minification));
          // TODO(124477502): Using uniqueMethodWithName("fooList") does not work.
          assertEquals(1, inspector.clazz(Service.class).allMethods().size());
          MethodSubject fooList = inspector.clazz(Service.class).allMethods().get(0);
          AnnotationSubject signature = fooList.annotation("dalvik.annotation.Signature");
          checkSignatureAnnotation(inspector, signature);
        });

        String fooImplFinalName = compileResult.inspector().clazz(FooImpl.class).getFinalName();

        compileResult
            .run(Main.class)
            .assertSuccessWithOutput(StringUtils.lines(fooImplFinalName, fooImplFinalName));
  }
}

class Main {
  public static void main(String... args) throws Exception {
    Method method = Service.class.getMethod("fooList");
    ParameterizedType type = (ParameterizedType) method.getGenericReturnType();
    Class<?> rawType = (Class<?>) type.getRawType();
    System.out.println(rawType.getName());

    // Convince R8 we only use subtypes to get class merging of Foo into FooImpl.
    Foo<String> foo = new FooImpl<>();
    System.out.println(foo.getClass().getCanonicalName());
  }
}

interface Service {
  Foo<String> fooList();
}

interface Foo<T> {}

class FooImpl<T> implements Foo<T> {}
