// 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.desugar.desugaredlibrary.gson;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import dalvik.system.PathClassLoader;
import java.sql.SQLDataException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
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 GetGenericInterfaceTest extends DesugaredLibraryTestBase {

  private final TestParameters parameters;
  private final boolean shrinkDesugaredLibrary;

  @Parameters(name = "{1}, shrinkDesugaredLibrary: {0}")
  public static List<Object[]> data() {
    return buildParameters(
        BooleanUtils.values(), getTestParameters().withDexRuntimes().withAllApiLevels().build());
  }

  public GetGenericInterfaceTest(boolean shrinkDesugaredLibrary, TestParameters parameters) {
    this.shrinkDesugaredLibrary = shrinkDesugaredLibrary;
    this.parameters = parameters;
  }

  @Test
  public void testCustomCollectionD8() throws Exception {
    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
    String stdOut =
        testForD8()
            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
            .addInnerClasses(GetGenericInterfaceTest.class)
            .setMinApi(parameters.getApiLevel())
            .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
            .compile()
            .addDesugaredCoreLibraryRunClassPath(
                this::buildDesugaredLibrary,
                parameters.getApiLevel(),
                keepRuleConsumer.get(),
                shrinkDesugaredLibrary)
            .run(parameters.getRuntime(), Executor.class)
            .assertSuccess()
            .getStdOut();
    assertValidInterfaces(stdOut);
  }

  @Test
  public void testCustomCollectionR8() throws Exception {
    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
    String stdOut =
        testForR8(Backend.DEX)
            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
            .addInnerClasses(GetGenericInterfaceTest.class)
            .addKeepMainRule(Executor.class)
            .noMinification()
            .setMinApi(parameters.getApiLevel())
            .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
            .compile()
            .addDesugaredCoreLibraryRunClassPath(
                this::buildDesugaredLibrary,
                parameters.getApiLevel(),
                keepRuleConsumer.get(),
                shrinkDesugaredLibrary)
            .run(parameters.getRuntime(), Executor.class)
            .assertSuccess()
            .getStdOut();
    assertValidInterfaces(stdOut);
  }

  private void assertValidInterfaces(String stdOut) {
    // The value of getGenericInterfaces has to be the value of getInterfaces with generic types.
    // Here are two examples:
    //  - class A implements I {}
    //    getInterfaces -> [interface I]
    //    getGenericInterfaces -> [interface I]
    //  - class B<E> implements J<E> {}
    //    getInterfaces -> [interface J]
    //    getGenericInterfaces -> [J<E>]
    // Both arrays have to be of the same size and each class has to be present in the same order.
    String[] lines = stdOut.split("\n");
    for (int i = 0; i < lines.length; i += 4) {
      String className = lines[i];
      String[] interfaces1 = lines[i + 1].split("(, com|, interface|, j)");
      String[] interfaces2 = lines[i + 2].split("(, com|, interface|, j)");
      assertEquals(
          "Invalid number of interfaces in "
              + className
              + "\n "
              + Arrays.toString(interfaces1)
              + "\n "
              + Arrays.toString(interfaces2),
          interfaces1.length,
          interfaces2.length);
      // Ignore the empty list of interface case.
      if (!interfaces1[0].equals("[]")) {
        for (int j = 0; j < interfaces1.length; j++) {
          String interfaceName = interfaces1[j].substring("interface ".length()).trim();
          while (interfaceName.charAt(interfaceName.length() - 1) == ']') {
            interfaceName = interfaceName.substring(0, interfaceName.length() - 2).trim();
          }
          assertTrue(
              "Invalid interface in " + className + "\n " + interfaces1[j] + "\n " + interfaces2[j],
              interfaces2[j].contains(interfaceName));
        }
      }
    }
  }

  @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
  static class Executor {

    // The output of the test is, in stdOut, composed of 4 lines entries:
    // line 1: class name
    // line 2: getInterfaces() for the class
    // line 3: getGenericInterfaces() for the class
    // line 4: empty.
    public static void main(String[] args) {
      mapTest();
      collectionTest();
      collectionMapTest();
      sqlDateTest();
    }

    private static void mapTest() {
      System.out.println(NullableConcurrentHashMapExtendDifferentLetters.class);
      System.out.println(
          Arrays.toString(NullableConcurrentHashMapExtendDifferentLetters.class.getInterfaces()));
      System.out.println(
          Arrays.toString(
              NullableConcurrentHashMapExtendDifferentLetters.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(NullableConcurrentHashMapExtend.class);
      System.out.println(Arrays.toString(NullableConcurrentHashMapExtend.class.getInterfaces()));
      System.out.println(
          Arrays.toString(NullableConcurrentHashMapExtend.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(NullableConcurrentHashMapExtendZ.class);
      System.out.println(Arrays.toString(NullableConcurrentHashMapExtendZ.class.getInterfaces()));
      System.out.println(
          Arrays.toString(NullableConcurrentHashMapExtendZ.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(NullableConcurrentHashMapImplement.class);
      System.out.println(Arrays.toString(NullableConcurrentHashMapImplement.class.getInterfaces()));
      System.out.println(
          Arrays.toString(NullableConcurrentHashMapImplement.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(NullableConcurrentHashMapImplementZ.class);
      System.out.println(
          Arrays.toString(NullableConcurrentHashMapImplementZ.class.getInterfaces()));
      System.out.println(
          Arrays.toString(NullableConcurrentHashMapImplementZ.class.getGenericInterfaces()));
      System.out.println();
    }

    private static void collectionTest() {
      System.out.println(NullableArrayListExtend.class);
      System.out.println(Arrays.toString(NullableArrayListExtend.class.getInterfaces()));
      System.out.println(Arrays.toString(NullableArrayListExtend.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(NullableArrayListExtendZ.class);
      System.out.println(Arrays.toString(NullableArrayListExtendZ.class.getInterfaces()));
      System.out.println(Arrays.toString(NullableArrayListExtendZ.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(NullableArrayListImplement.class);
      System.out.println(Arrays.toString(NullableArrayListImplement.class.getInterfaces()));
      System.out.println(Arrays.toString(NullableArrayListImplement.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(NullableArrayListImplementZ.class);
      System.out.println(Arrays.toString(NullableArrayListImplementZ.class.getInterfaces()));
      System.out.println(Arrays.toString(NullableArrayListImplementZ.class.getGenericInterfaces()));
      System.out.println();
    }

    private static void collectionMapTest() {
      System.out.println(CollectionMapImplements2.class);
      System.out.println(Arrays.toString(CollectionMapImplements2.class.getInterfaces()));
      System.out.println(Arrays.toString(CollectionMapImplements2.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(CollectionMapExtendImplement.class);
      System.out.println(Arrays.toString(CollectionMapExtendImplement.class.getInterfaces()));
      System.out.println(
          Arrays.toString(CollectionMapExtendImplement.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(CollectionMapImplements2Integer1.class);
      System.out.println(Arrays.toString(CollectionMapImplements2Integer1.class.getInterfaces()));
      System.out.println(
          Arrays.toString(CollectionMapImplements2Integer1.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(CollectionMapExtendImplementInteger1.class);
      System.out.println(
          Arrays.toString(CollectionMapExtendImplementInteger1.class.getInterfaces()));
      System.out.println(
          Arrays.toString(CollectionMapExtendImplementInteger1.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(CollectionMapImplements2Integer2.class);
      System.out.println(Arrays.toString(CollectionMapImplements2Integer2.class.getInterfaces()));
      System.out.println(
          Arrays.toString(CollectionMapImplements2Integer2.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(CollectionMapExtendImplementInteger2.class);
      System.out.println(
          Arrays.toString(CollectionMapExtendImplementInteger2.class.getInterfaces()));
      System.out.println(
          Arrays.toString(CollectionMapExtendImplementInteger2.class.getGenericInterfaces()));
      System.out.println();
    }

    private static void sqlDateTest() {
      System.out.println(MySQLDataException.class);
      System.out.println(Arrays.toString(MySQLDataException.class.getInterfaces()));
      System.out.println(Arrays.toString(MySQLDataException.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(MyDate.class);
      System.out.println(Arrays.toString(MyDate.class.getInterfaces()));
      System.out.println(Arrays.toString(MyDate.class.getGenericInterfaces()));
      System.out.println();

      System.out.println(MyDateZ.class);
      System.out.println(Arrays.toString(MyDateZ.class.getInterfaces()));
      System.out.println(Arrays.toString(MyDateZ.class.getGenericInterfaces()));
      System.out.println();
    }
  }

  interface MyInterface<Z> {
    void print(Z z);
  }

  static class NullableConcurrentHashMapExtendDifferentLetters<R, T>
      extends ConcurrentHashMap<R, T> {
    NullableConcurrentHashMapExtendDifferentLetters() {
      super();
    }
  }

  static class NullableConcurrentHashMapExtend<K, V> extends ConcurrentHashMap<K, V> {
    NullableConcurrentHashMapExtend() {
      super();
    }
  }

  static class NullableConcurrentHashMapImplement<K, V> implements ConcurrentMap<K, V> {
    @Override
    public int size() {
      return 0;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean containsKey(Object o) {
      return false;
    }

    @Override
    public boolean containsValue(Object o) {
      return false;
    }

    @Override
    public V get(Object o) {
      return null;
    }

    @Override
    public V put(K k, V v) {
      return null;
    }

    @Override
    public V remove(Object o) {
      return null;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> map) {}

    @Override
    public void clear() {}

    @Override
    public Set<K> keySet() {
      return null;
    }

    @Override
    public Collection<V> values() {
      return null;
    }

    @Override
    public Set<Entry<K, V>> entrySet() {
      return null;
    }

    @Override
    public V putIfAbsent(K k, V v) {
      return null;
    }

    @Override
    public boolean remove(Object o, Object o1) {
      return false;
    }

    @Override
    public boolean replace(K k, V v, V v1) {
      return false;
    }

    @Override
    public V replace(K k, V v) {
      return null;
    }
  }

  static class NullableConcurrentHashMapExtendZ<K, V> extends ConcurrentHashMap<K, V>
      implements MyInterface<K> {
    NullableConcurrentHashMapExtendZ() {
      super();
    }

    @Override
    public void print(K k) {}
  }

  static class NullableConcurrentHashMapImplementZ<K, V>
      implements ConcurrentMap<K, V>, MyInterface<K> {
    @Override
    public int size() {
      return 0;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean containsKey(Object o) {
      return false;
    }

    @Override
    public boolean containsValue(Object o) {
      return false;
    }

    @Override
    public V get(Object o) {
      return null;
    }

    @Override
    public V put(K k, V v) {
      return null;
    }

    @Override
    public V remove(Object o) {
      return null;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> map) {}

    @Override
    public void clear() {}

    @Override
    public Set<K> keySet() {
      return null;
    }

    @Override
    public Collection<V> values() {
      return null;
    }

    @Override
    public Set<Entry<K, V>> entrySet() {
      return null;
    }

    @Override
    public V putIfAbsent(K k, V v) {
      return null;
    }

    @Override
    public boolean remove(Object o, Object o1) {
      return false;
    }

    @Override
    public boolean replace(K k, V v, V v1) {
      return false;
    }

    @Override
    public V replace(K k, V v) {
      return null;
    }

    @Override
    public void print(K k) {}
  }

  static class NullableArrayListExtend<E> extends ArrayList<E> {
    NullableArrayListExtend() {
      super();
    }
  }

  static class NullableArrayListImplement<E> implements List<E> {
    @Override
    public int size() {
      return 0;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean contains(Object o) {
      return false;
    }

    @Override
    public Iterator<E> iterator() {
      return null;
    }

    @Override
    public Object[] toArray() {
      return new Object[0];
    }

    @Override
    public <T> T[] toArray(T[] ts) {
      return null;
    }

    @Override
    public boolean add(E e) {
      return false;
    }

    @Override
    public boolean remove(Object o) {
      return false;
    }

    @Override
    public boolean containsAll(Collection<?> collection) {
      return false;
    }

    @Override
    public boolean addAll(Collection<? extends E> collection) {
      return false;
    }

    @Override
    public boolean addAll(int i, Collection<? extends E> collection) {
      return false;
    }

    @Override
    public boolean removeAll(Collection<?> collection) {
      return false;
    }

    @Override
    public boolean retainAll(Collection<?> collection) {
      return false;
    }

    @Override
    public void clear() {}

    @Override
    public E get(int i) {
      return null;
    }

    @Override
    public E set(int i, E e) {
      return null;
    }

    @Override
    public void add(int i, E e) {}

    @Override
    public E remove(int i) {
      return null;
    }

    @Override
    public int indexOf(Object o) {
      return 0;
    }

    @Override
    public int lastIndexOf(Object o) {
      return 0;
    }

    @Override
    public ListIterator<E> listIterator() {
      return null;
    }

    @Override
    public ListIterator<E> listIterator(int i) {
      return null;
    }

    @Override
    public List<E> subList(int i, int i1) {
      return null;
    }
  }

  static class NullableArrayListExtendZ<E> extends ArrayList<E> implements MyInterface<E> {
    NullableArrayListExtendZ() {
      super();
    }

    @Override
    public void print(E e) {}
  }

  static class NullableArrayListImplementZ<E> implements List<E>, MyInterface<E> {
    @Override
    public int size() {
      return 0;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean contains(Object o) {
      return false;
    }

    @Override
    public Iterator<E> iterator() {
      return null;
    }

    @Override
    public Object[] toArray() {
      return new Object[0];
    }

    @Override
    public <T> T[] toArray(T[] ts) {
      return null;
    }

    @Override
    public boolean add(E e) {
      return false;
    }

    @Override
    public boolean remove(Object o) {
      return false;
    }

    @Override
    public boolean containsAll(Collection<?> collection) {
      return false;
    }

    @Override
    public boolean addAll(Collection<? extends E> collection) {
      return false;
    }

    @Override
    public boolean addAll(int i, Collection<? extends E> collection) {
      return false;
    }

    @Override
    public boolean removeAll(Collection<?> collection) {
      return false;
    }

    @Override
    public boolean retainAll(Collection<?> collection) {
      return false;
    }

    @Override
    public void clear() {}

    @Override
    public E get(int i) {
      return null;
    }

    @Override
    public E set(int i, E e) {
      return null;
    }

    @Override
    public void add(int i, E e) {}

    @Override
    public E remove(int i) {
      return null;
    }

    @Override
    public int indexOf(Object o) {
      return 0;
    }

    @Override
    public int lastIndexOf(Object o) {
      return 0;
    }

    @Override
    public ListIterator<E> listIterator() {
      return null;
    }

    @Override
    public ListIterator<E> listIterator(int i) {
      return null;
    }

    @Override
    public List<E> subList(int i, int i1) {
      return null;
    }

    @Override
    public void print(E e) {}
  }

  static class CollectionMapImplements2<R, C> implements Iterable<R>, Map<R, C> {
    @Override
    public Iterator<R> iterator() {
      return null;
    }

    @Override
    public int size() {
      return 0;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean containsKey(Object o) {
      return false;
    }

    @Override
    public boolean containsValue(Object o) {
      return false;
    }

    @Override
    public C get(Object o) {
      return null;
    }

    @Override
    public C put(R r, C c) {
      return null;
    }

    @Override
    public C remove(Object o) {
      return null;
    }

    @Override
    public void putAll(Map<? extends R, ? extends C> map) {}

    @Override
    public void clear() {}

    @Override
    public Set<R> keySet() {
      return null;
    }

    @Override
    public Collection<C> values() {
      return null;
    }

    @Override
    public Set<Entry<R, C>> entrySet() {
      return null;
    }
  }

  static class CollectionMapExtendImplement<R, C> extends HashMap<R, C> implements Iterable<R> {
    @Override
    public Iterator<R> iterator() {
      return null;
    }

    @Override
    public int size() {
      return 0;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean containsKey(Object o) {
      return false;
    }

    @Override
    public boolean containsValue(Object o) {
      return false;
    }

    @Override
    public C get(Object o) {
      return null;
    }

    @Override
    public C put(R r, C c) {
      return null;
    }

    @Override
    public C remove(Object o) {
      return null;
    }

    @Override
    public void putAll(Map<? extends R, ? extends C> map) {}

    @Override
    public void clear() {}

    @Override
    public Set<R> keySet() {
      return null;
    }

    @Override
    public Collection<C> values() {
      return null;
    }

    @Override
    public Set<Entry<R, C>> entrySet() {
      return null;
    }
  }

  static class CollectionMapImplements2Integer1<C>
      implements Iterable<PathClassLoader>, Map<PathClassLoader, C> {
    @Override
    public Iterator<PathClassLoader> iterator() {
      return null;
    }

    @Override
    public int size() {
      return 0;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean containsKey(Object o) {
      return false;
    }

    @Override
    public boolean containsValue(Object o) {
      return false;
    }

    @Override
    public C get(Object o) {
      return null;
    }

    @Override
    public C put(PathClassLoader unsafe, C c) {
      return null;
    }

    @Override
    public C remove(Object o) {
      return null;
    }

    @Override
    public void putAll(Map<? extends PathClassLoader, ? extends C> map) {}

    @Override
    public void clear() {}

    @Override
    public Set<PathClassLoader> keySet() {
      return null;
    }

    @Override
    public Collection<C> values() {
      return null;
    }

    @Override
    public Set<Entry<PathClassLoader, C>> entrySet() {
      return null;
    }
  }

  static class CollectionMapExtendImplementInteger1<C> extends HashMap<PathClassLoader, C>
      implements Iterable<PathClassLoader> {
    @Override
    public Iterator<PathClassLoader> iterator() {
      return null;
    }
  }

  static class CollectionMapImplements2Integer2<R> implements Iterable<R>, Map<R, PathClassLoader> {
    @Override
    public Iterator<R> iterator() {
      return null;
    }

    @Override
    public int size() {
      return 0;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean containsKey(Object o) {
      return false;
    }

    @Override
    public boolean containsValue(Object o) {
      return false;
    }

    @Override
    public PathClassLoader get(Object o) {
      return null;
    }

    @Override
    public PathClassLoader put(R r, PathClassLoader unsafe) {
      return null;
    }

    @Override
    public PathClassLoader remove(Object o) {
      return null;
    }

    @Override
    public void putAll(Map<? extends R, ? extends PathClassLoader> map) {}

    @Override
    public void clear() {}

    @Override
    public Set<R> keySet() {
      return null;
    }

    @Override
    public Collection<PathClassLoader> values() {
      return null;
    }

    @Override
    public Set<Entry<R, PathClassLoader>> entrySet() {
      return null;
    }
  }

  static class CollectionMapExtendImplementInteger2<R> extends HashMap<R, PathClassLoader>
      implements Iterable<R> {
    @Override
    public Iterator<R> iterator() {
      return null;
    }
  }

  // SQLDataException implements Iterable<Throwable>.
  static class MySQLDataException extends SQLDataException {}

  // java.util.Date for the extra dispatch case.
  static class MyDate extends Date {}

  static class MyDateZ<Z> extends Date implements MyInterface<Z> {
    @Override
    public void print(Z z) {}
  }
}
