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

import static com.google.common.base.Predicates.alwaysFalse;
import static com.google.common.base.Predicates.alwaysTrue;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestDiagnosticMessagesImpl;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GenericSignature;
import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
import com.android.tools.r8.graph.GenericSignatureContextBuilder.TypeParameterContext;
import com.android.tools.r8.graph.GenericSignaturePartialTypeArgumentApplier;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.BiPredicateUtils;
import com.android.tools.r8.utils.MapUtils;
import com.google.common.collect.ImmutableMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
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 GenericSignaturePartialTypeArgumentApplierTest extends TestBase {

  private final TestParameters parameters;
  private final DexItemFactory itemFactory = new DexItemFactory();
  private final DexType objectType = itemFactory.objectType;

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

  public GenericSignaturePartialTypeArgumentApplierTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  @Test
  public void testVariablesInOuterPosition() throws Exception {
    runTest(
            ImmutableMap.of("T", objectType, "R", objectType),
            Collections.emptySet(),
            BiPredicateUtils.alwaysFalse(),
            alwaysTrue(),
            "(TT;)TR;",
            "(Ljava/lang/Object;)Ljava/lang/Object;")
        .assertNoMessages();
  }

  @Test
  public void testVariablesInInnerPosition() throws Exception {
    runTest(
            ImmutableMap.of("T", objectType, "R", objectType),
            Collections.emptySet(),
            BiPredicateUtils.alwaysFalse(),
            alwaysTrue(),
            "(LList<TT;>;)LList<TR;>;",
            "(LList<Ljava/lang/Object;>;)LList<Ljava/lang/Object;>;")
        .assertNoMessages();
  }

  @Test
  public void testRemovingPrunedLink() throws Exception {
    runTest(
            Collections.emptyMap(),
            Collections.emptySet(),
            BiPredicateUtils.alwaysTrue(),
            alwaysTrue(),
            "(LFoo<Ljava/lang/String;>.Bar<Ljava/lang/Integer;>;)"
                + "LFoo<Ljava/lang/String;>.Bar<Ljava/lang/Integer;>;",
            "(LFoo$Bar<Ljava/lang/Integer;>;)LFoo$Bar<Ljava/lang/Integer;>;")
        .assertNoMessages();
  }

  @Test
  public void testRemovedGenericArguments() throws Exception {
    runTest(
            Collections.emptyMap(),
            Collections.emptySet(),
            BiPredicateUtils.alwaysTrue(),
            alwaysFalse(),
            "(LFoo<Ljava/lang/String;>;)LFoo<Ljava/lang/String;>.Bar<Ljava/lang/Integer;>;",
            "(LFoo;)LFoo$Bar;")
        .assertNoMessages();
  }

  private TestDiagnosticMessages runTest(
      Map<String, DexType> substitutions,
      Set<String> liveVariables,
      BiPredicate<DexType, DexType> removedLink,
      Predicate<DexType> hasFormalTypeParameters,
      String initialSignature,
      String expectedRewrittenSignature)
      throws Exception {
    AppView<AppInfo> appView = computeAppView(AndroidApp.builder().build());
    GenericSignaturePartialTypeArgumentApplier argumentApplier =
        GenericSignaturePartialTypeArgumentApplier.build(
            appView,
            TypeParameterContext.empty()
                .addPrunedSubstitutions(
                    MapUtils.transform(
                        substitutions,
                        HashMap::new,
                        s -> s,
                        ClassTypeSignature::new,
                        (val1, val2) -> {
                          throw new Unreachable("No keys should be merged");
                        }))
                .addLiveParameters(liveVariables),
            removedLink,
            hasFormalTypeParameters);
    TestDiagnosticMessagesImpl diagnosticsHandler = new TestDiagnosticMessagesImpl();
    MethodTypeSignature methodTypeSignature =
        argumentApplier.visitMethodSignature(
            GenericSignature.parseMethodSignature(
                "foo", initialSignature, Origin.unknown(), itemFactory, diagnosticsHandler));
    diagnosticsHandler.assertNoMessages();
    String rewrittenSignature =
        argumentApplier.visitMethodSignature(methodTypeSignature).toString();
    assertEquals(expectedRewrittenSignature, rewrittenSignature);
    GenericSignature.parseMethodSignature(
        "foo", rewrittenSignature, Origin.unknown(), itemFactory, diagnosticsHandler);
    return diagnosticsHandler;
  }
}
