// 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.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
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)
        .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());
    }
  }
}
