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

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

import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.naming.testclasses.Greeting;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.FieldSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import org.junit.Test;

public class B128656974 extends TestBase {

  @Test
  public void testField() throws Exception {
    Class<?> main = TestClassMainForField.class;
    testForR8(Backend.DEX)
        .addProgramClasses(Greeting.class, Greeting.getGreetingBase(), TestClassSub.class, main)
        .enableNeverClassInliningAnnotations()
        .enableMergeAnnotations()
        .addKeepMainRule(main)
        .addKeepRules(
            "-keepclassmembernames class "
                + TestClassSub.class.getTypeName()
                + "{ static java.lang.String a; }")
        .run(main)
        .assertSuccessWithOutput(StringUtils.lines("TestClassSub.greeting", "TestClassSub.a"))
        .inspect(
            inspector -> {
              ClassSubject greetingBase = inspector.clazz(Greeting.getGreetingBase());
              assertThat(greetingBase, isPresent());
              FieldSubject greeting = greetingBase.uniqueFieldWithName("greeting");
              assertThat(greeting, isPresentAndRenamed());
              assertNotEquals("a", greeting.getFinalName());
            });
  }

  @NeverClassInline
  static class TestClassSub extends Greeting {
    // Since this name is kept, renaming of Greeting.greeting should avoid `a`.
    // Otherwise, we'll see Out-of-order field_ids due to the duplicate fields.
    static String a;

    TestClassSub() {
      greeting = "TestClassSub.greeting";
      a = "TestClassSub.a";
    }

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

  static class TestClassMainForField {
    public static void main(String[] args) {
      TestClassSub instance = new TestClassSub();
      System.out.println(instance.toString());
    }
  }

  @Test
  public void testMethod() throws Exception {
    Class<?> main = TestClassMainForMethod.class;
    testForR8(Backend.DEX)
        .addProgramClasses(TestClassBase.class, TestClassSub2.class, main)
        .enableMergeAnnotations()
        .enableNeverClassInliningAnnotations()
        .enableInliningAnnotations()
        .addKeepMainRule(main)
        .addKeepRules(
            "-keepclassmembernames class " + TestClassSub2.class.getTypeName() + "{ void a(...); }")
        .run(main)
        .assertSuccessWithOutput(StringUtils.lines("TestClassSub2::a", "TestClassBase::foo"))
        .inspect(
            inspector -> {
              ClassSubject base = inspector.clazz(TestClassBase.class);
              assertThat(base, isPresent());
              MethodSubject foo = base.uniqueMethodWithName("foo");
              assertThat(foo, isPresentAndRenamed());
              assertNotEquals("a", foo.getFinalName());
            });
  }

  @NeverMerge
  static class TestClassBase {
    @NeverInline
    void foo() {
      System.out.println("TestClassBase::foo");
    }
  }

  @NeverClassInline
  static class TestClassSub2 extends TestClassBase {
    // Since this name is kept, renaming of TestClassBase#foo should avoid `a`.
    // Otherwise, we'll see Out-of-order method_ids due to the duplicate methods.
    @NeverInline
    void a() {
      System.out.println("TestClassSub2::a");
    }
  }

  static class TestClassMainForMethod {
    public static void main(String[] args) {
      TestClassSub2 instance = new TestClassSub2();
      instance.a();
      instance.foo();
    }
  }
}
