// 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;

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.assertNotEquals;
import static org.junit.Assume.assumeFalse;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.utils.BooleanUtils;
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 org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

/**
 * Tests that a reserved field name from a given class A is taken into account when renaming the
 * fields in subclasses of A.
 */
@RunWith(Parameterized.class)
public class ReservedFieldNameInSuperClassTest extends TestBase {

  private final boolean reserveName;

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

  public ReservedFieldNameInSuperClassTest(boolean reserveName) {
    this.reserveName = reserveName;
  }

  @Test
  public void testProgramClass() throws Exception {
    String expectedOutput = StringUtils.lines("A.a", "ASub1.foo", "ASub2.bar");
    CodeInspector inspector =
        testForR8(Backend.DEX)
            .addProgramClasses(A.class, ASub1.class, ASub2.class, TestClass.class)
            .enableClassInliningAnnotations()
            .addKeepMainRule(TestClass.class)
            .addKeepRules(
                reserveName
                    ? "-keepclassmembernames class " + A.class.getTypeName() + "{ <fields>; }"
                    : "")
            .run(TestClass.class)
            .assertSuccessWithOutput(expectedOutput)
            .inspector();

    ClassSubject testClassForFieldSubject = inspector.clazz(A.class);
    assertThat(testClassForFieldSubject, isPresent());

    FieldSubject aFieldSubject = testClassForFieldSubject.uniqueFieldWithName("a");
    assertThat(aFieldSubject, isPresent());

    // Fields are visited/renamed according to the class hierarchy order. Thus, the field A.a will
    // be visited first and assigned the name a. As it ends up receiving the same name as in the
    // original program, it has not technically been renamed.
    assertThat(aFieldSubject, not(isRenamed()));

    inspect(inspector);
  }

  @Test
  public void testLibraryClass() throws Exception {
    assumeFalse("No need to add keep rules for the library", reserveName);

    String expectedOutput = StringUtils.lines("A.a", "ASub1.foo", "ASub2.bar");
    testForR8(Backend.DEX)
        .addProgramClasses(ASub1.class, ASub2.class, TestClass.class)
        .addLibraryClasses(A.class)
        .addLibraryFiles(runtimeJar(Backend.DEX))
        .enableClassInliningAnnotations()
        .addKeepMainRule(TestClass.class)
        .compile()
        .addRunClasspathFiles(testForD8().addProgramClasses(A.class).compile().writeToZip())
        .run(TestClass.class)
        .assertSuccessWithOutput(expectedOutput)
        .inspect(this::inspect);
  }

  private void inspect(CodeInspector inspector) {
    ClassSubject aSub1ClassSubject = inspector.clazz(ASub1.class);
    assertThat(aSub1ClassSubject, isPresent());

    FieldSubject fooFieldSubject = aSub1ClassSubject.uniqueFieldWithName("foo");
    assertThat(fooFieldSubject, isPresent());
    assertThat(fooFieldSubject, isRenamed());
    assertNotEquals("a", fooFieldSubject.getFinalName());

    ClassSubject aSub2ClassSubject = inspector.clazz(ASub2.class);
    assertThat(aSub2ClassSubject, isPresent());

    FieldSubject barFieldSubject = aSub2ClassSubject.uniqueFieldWithName("bar");
    assertThat(barFieldSubject, isPresent());
    assertThat(barFieldSubject, isRenamed());
    assertNotEquals("a", barFieldSubject.getFinalName());

    // Verify that ASub1.foo and ASub2.bar has been renamed to the same name.
    //
    // Note that this is not a requirement for the correctness of the field name minifier. The field
    // name minifier is in principle free to choose different names for ASub1.foo and ASub2.bar, but
    // this would have a negative impact on code size.
    assertEquals(fooFieldSubject.getFinalName(), barFieldSubject.getFinalName());
  }

  static class A {

    static String a;
  }

  static class ASub1 extends A {

    static String foo;

    ASub1() {
      a = "A.a";
      foo = "ASub1.foo";
    }

    @Override
    public String toString() {
      return a + System.lineSeparator() + foo;
    }
  }

  static class ASub2 extends A {

    static String bar;

    ASub2() {
      bar = "ASub2.bar";
    }

    @Override
    public String toString() {
      return bar;
    }
  }

  static class TestClass {

    public static void main(String[] args) {
      System.out.println(new ASub1());
      System.out.println(new ASub2());
    }
  }
}
