// Copyright (c) 2018, 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.applymapping.sourcelibrary;

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

import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.NeverPropagateValue;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.StringUtils;
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 com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

// AbstractChecker -> X:
@NeverMerge
abstract class AbstractChecker {
  // String tag -> p
  @NeverPropagateValue private String tag = "PrivateInitialTag_AbstractChecker";

  // check() -> x
  private void check() {
    System.out.println("AbstractChecker#check:" + tag);
  }

  // foo() -> a
  protected void foo() {
    check();
  }
}

// ConcreteChecker -> Y:
class ConcreteChecker extends AbstractChecker {
  // This should not be conflict with AbstractChecker#tag due to the access control.
  // String tag -> q
  private String tag = "PrivateInitialTag_ConcreteChecker";

  ConcreteChecker(String tag) {
    this.tag = tag;
  }

  // This should not be conflict with AbstractChecker#check due to the access control.
  // check() -> y
  private void check() {
    System.out.println("ConcreteChecker#check:" + tag);
  }

  // foo() -> a
  @Override
  protected void foo() {
    super.foo();
    check();
  }
}

class MemberResolutionTestMain {
  public static void main(String[] args) {
    ConcreteChecker c = new ConcreteChecker("NewTag");
    c.foo();
  }
}

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

  private final TestParameters parameters;

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

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

  @Test
  public void testPrivateMethodsWithSameName() throws Exception {
    String pkg = this.getClass().getPackage().getName();
    Path mapPath = temp.newFile("test-mapping.txt").toPath();
    List<String> pgMap =
        ImmutableList.of(
            pkg + ".AbstractChecker -> " + pkg + ".X:",
            "  java.lang.String tag -> p",
            "  void check() -> x",
            "  void foo() -> a",
            pkg + ".ConcreteChecker -> " + pkg + ".Y:",
            "  java.lang.String tag -> q",
            "  void check() -> y",
            "  void foo() -> a");
    FileUtils.writeTextFile(mapPath, pgMap);

    String expectedOutput =
        StringUtils.lines(
            "AbstractChecker#check:PrivateInitialTag_AbstractChecker",
            "ConcreteChecker#check:NewTag");

    if (parameters.isCfRuntime()) {
      testForJvm()
          .addTestClasspath()
          .run(parameters.getRuntime(), MemberResolutionTestMain.class)
          .assertSuccessWithOutput(expectedOutput);
    }

    CodeInspector inspector =
        testForR8(parameters.getBackend())
            .addProgramClasses(
                AbstractChecker.class, ConcreteChecker.class, MemberResolutionTestMain.class)
            .addKeepMainRule(MemberResolutionTestMain.class)
            .addKeepRules("-applymapping " + mapPath)
            .enableMemberValuePropagationAnnotations()
            .enableMergeAnnotations()
            .addOptionsModification(options -> options.enableInlining = false)
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), MemberResolutionTestMain.class)
            .assertSuccessWithOutput(expectedOutput)
            .inspector();

    ClassSubject base = inspector.clazz(AbstractChecker.class);
    assertThat(base, isPresent());
    FieldSubject p = base.field("java.lang.String", "tag");
    assertThat(p, isPresent());
    assertThat(p, isRenamed());
    assertEquals("p", p.getFinalName());
    MethodSubject x = base.method("void", "check", ImmutableList.of());
    assertThat(x, isPresent());
    assertThat(x, isRenamed());
    assertEquals("x", x.getFinalName());

    ClassSubject sub = inspector.clazz(ConcreteChecker.class);
    assertThat(sub, isPresent());
    FieldSubject q = sub.field("java.lang.String", "tag");
    assertThat(q, isPresent());
    assertThat(q, isRenamed());
    assertEquals("q", q.getFinalName());
    MethodSubject y = sub.method("void", "check", ImmutableList.of());
    assertThat(y, isPresent());
    assertThat(y, isRenamed());
    assertEquals("y", y.getFinalName());
  }
}
