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

import static junit.framework.TestCase.assertEquals;

import com.android.tools.r8.LibraryDesugaringTestConfiguration;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.DexRuntime;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class DuplicateAPIDesugaredLibTest extends DesugaredLibraryTestBase {

  private final TestParameters parameters;
  private final boolean shrinkDesugaredLibrary;
  private static final AndroidApiLevel MIN_SUPPORTED = AndroidApiLevel.N;

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

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

  @Test
  public void testLib() throws Exception {
    for (Boolean supportAllCallbacksFromLibrary : BooleanUtils.values()) {
      Box<Path> desugaredLibBox = new Box<>();
      Path customLib =
          testForD8()
              .addProgramClasses(CustomLibClass.class)
              .setMinApi(AndroidApiLevel.B)
              .compile()
              .writeToZip();
      String stdOut =
          testForD8()
              .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
              .setMinApi(AndroidApiLevel.B)
              .addProgramClasses(Executor.class)
              .addLibraryClasses(CustomLibClass.class)
              .enableCoreLibraryDesugaring(
                  LibraryDesugaringTestConfiguration.builder()
                      .setMinApi(AndroidApiLevel.B)
                      .dontAddRunClasspath()
                      .build())
              .compile()
              .addDesugaredCoreLibraryRunClassPath(
                  (AndroidApiLevel api) -> {
                    desugaredLibBox.set(
                        this.buildDesugaredLibrary(
                            api,
                            opt ->
                                opt.desugaredLibraryConfiguration =
                                    configurationWithSupportAllCallbacksFromLibrary(
                                        opt, true, parameters, supportAllCallbacksFromLibrary)));
                    return desugaredLibBox.get();
                  },
                  AndroidApiLevel.B)
              .addRunClasspathFiles(customLib)
              .run(new DexRuntime(DexVm.ART_9_0_0_HOST), Executor.class)
              .assertSuccess()
              .getStdOut();
      assertDupMethod(new CodeInspector(desugaredLibBox.get()), supportAllCallbacksFromLibrary);
      assertLines2By2Correct(stdOut);
    }
  }

  private void assertDupMethod(CodeInspector inspector, boolean supportAllCallbacksFromLibrary) {
    ClassSubject clazz = inspector.clazz("j$.util.concurrent.ConcurrentHashMap");
    int numForEachMethods =
        isJDK11DesugaredLibrary()
            ? supportAllCallbacksFromLibrary ? 4 : 3
            : supportAllCallbacksFromLibrary ? 2 : 1;
    assertEquals(
        numForEachMethods,
        clazz.virtualMethods().stream().filter(m -> m.getOriginalName().equals("forEach")).count());
  }

  static class Executor {

    public static void main(String[] args) {
      Map<Integer, Double> map = new ConcurrentHashMap<>();
      map.put(1, 1.1);
      map.put(2, 2.2);
      BiConsumer<Integer, Double> biConsumer = (x, y) -> System.out.print(" " + x + " " + y);
      map.forEach(biConsumer);
      System.out.println();
      CustomLibClass.javaForEach(map, biConsumer);
    }
  }

  // This class will be put at compilation time as library and on the runtime class path.
  // This class is convenient for easy testing. Each method plays the role of methods in the
  // platform APIs for which argument/return values need conversion.
  static class CustomLibClass {

    @SuppressWarnings("WeakerAccess")
    public static <K, V> void javaForEach(Map<K, V> map, BiConsumer<K, V> consumer) {
      map.forEach(consumer);
    }
  }
}
