// 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.shaking.fields.prvt;

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

import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.shaking.fields.FieldsTestBase;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableSet;
import java.util.Collection;
import java.util.Set;
import org.junit.Test;

@NeverMerge
class Super {
  private int f1;
}

@NeverMerge
class Sub extends Super {
  private int f2;
}

@NeverMerge
class SubSub extends Sub {
  private int f3;
}

class Main {

  private static void printField(Class<?> clazz, String name) {
    try {
      clazz.getDeclaredField(name);
      System.out.println(clazz.getSimpleName() + "." + name + " found");
    } catch (NoSuchFieldException e) {
      System.out.println(clazz.getSimpleName() + "." + name + " not found");
    }
  }

  public static void main(String[] args) {
    printField(Super.class, "f1");
    printField(Sub.class, "f2");
    printField(SubSub.class, "f3");
  }
}

public class PrivateFieldsTest extends FieldsTestBase {

  public Collection<Class<?>> getClasses() {
    return ImmutableSet.of(Super.class, Sub.class, SubSub.class, getMainClass());
  }

  public Class<?> getMainClass() {
    return Main.class;
  }

  private void checkFields(CodeInspector inspector, Set<String> expected) {
    ClassSubject superSubject = inspector.clazz(Super.class);
    assertThat(superSubject, isPresent());
    assertEquals(superSubject.field("int", "f1").isPresent(), expected.contains("f1"));
    ClassSubject subSubject = inspector.clazz(Sub.class);
    assertThat(subSubject, isPresent());
    assertEquals(subSubject.field("int", "f2").isPresent(), expected.contains("f2"));
    ClassSubject subSubSubject = inspector.clazz(SubSub.class);
    assertThat(subSubSubject, isPresent());
    assertEquals(subSubSubject.field("int", "f3").isPresent(), expected.contains("f3"));
  }

  private void checkAllFields(CodeInspector inspector) {
    checkFields(inspector, ImmutableSet.of("f1", "f2", "f3"));
  }

  private void checkOnlyF1(CodeInspector inspector) {
    checkFields(inspector, ImmutableSet.of("f1"));
  }

  private void checkOnlyF2(CodeInspector inspector) {
    checkFields(inspector, ImmutableSet.of("f2"));
  }

  private void checkOnlyF3(CodeInspector inspector) {
    checkFields(inspector, ImmutableSet.of("f3"));
  }

  @Test
  public void testKeepAllFieldsWithWildcard() throws Throwable {
    runTest("-keep class **.SubSub { *; }", this::checkAllFields, allFieldsOutput());
  }

  @Test
  public void testKeepAllFieldsWithNameWildcard() throws Throwable {
    runTest("-keep class **.SubSub { int f*; }", this::checkAllFields, allFieldsOutput());
  }

  @Test
  public void testKeepAllFieldsWithFields() throws Throwable {
    runTest("-keep class **.SubSub { <fields>; }", this::checkAllFields, allFieldsOutput());
  }

  @Test
  public void testKeepF1() throws Throwable {
    runTest("-keep class **.SubSub { int f1; }", this::checkOnlyF1, onlyF1Output());
  }

  @Test
  public void testKeepF2() throws Throwable {
    runTest("-keep class **.SubSub { int f2; }", this::checkOnlyF2, onlyF2Output());
  }

  @Test
  public void testKeepF3() throws Throwable {
    runTest("-keep class **.SubSub { int f3; }", this::checkOnlyF3, onlyF3Output());
  }

  @Test
  public void testKeepF1WithExtends() throws Throwable {
    runTest("-keep class * extends **.Sub { int f1; }", this::checkOnlyF1, onlyF1Output());
  }

  @Test
  public void testKeepF2WithExtends() throws Throwable {
    runTest("-keep class * extends **.Sub { int f2; }", this::checkOnlyF2, onlyF2Output());
  }

  @Test
  public void testKeepF3WithExtends() throws Throwable {
    runTest("-keep class * extends **.Sub { int f3; }", this::checkOnlyF3, onlyF3Output());
  }
}
