// 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.keepclassmembers.b115867670;

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.assertThat;

import com.android.tools.r8.graph.invokesuper.Consumer;
import com.android.tools.r8.shaking.forceproguardcompatibility.ProguardCompatibilityTestBase;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@interface JsonClass {}

@JsonClass
class Foo {

  final Interaction[] interactions;

  public Foo(Interaction[] interactions) {
    this.interactions = interactions;
  }

  @JsonClass
  static class Interaction {
    final Request request;

    Interaction(Request request) {
      this.request = request;
    }
  }

  @JsonClass
  static class Request {
    final String path;

    Request(String path) {
      this.path = path;
    }
  }
}

class Main {

  public static void main(String[] args) {
    System.out.println(Foo.class);
  }
}

@RunWith(Parameterized.class)
public class B115867670 extends ProguardCompatibilityTestBase {
  private final String pkg = getClass().getPackage().getName();
  private final Shrinker shrinker;
  private final static List<Class> CLASSES = ImmutableList.of(
      JsonClass.class, Foo.class, Foo.Interaction.class, Foo.Request.class, Main.class);

  @Parameters(name = "shrinker: {0}")
  public static Collection<Object> data() {
    return ImmutableList.of(Shrinker.PROGUARD6, Shrinker.R8, Shrinker.R8_CF);
  }

  public B115867670(Shrinker shrinker) {
    this.shrinker = shrinker;
  }

  public void runTest(String additionalKeepRules, Consumer<CodeInspector> inspection)
      throws Exception {
    ImmutableList.Builder<String> builder = ImmutableList.builder();
    builder
        .add("-keep @interface **.JsonClass")
        .add("-keep class **.Main {")
        .add("  public static void main(java.lang.String[]);")
        .add("}")
        .add(additionalKeepRules);
    CodeInspector inspector = inspectAfterShrinking(shrinker, CLASSES, builder.build());
    inspection.accept(inspector);
  }

  private void checkNoKeepClassMembers(CodeInspector inspector) {
    assertThat(inspector.clazz(Main.class), isPresent());
    assertThat(inspector.clazz(Foo.class), isPresent());
    assertThat(inspector.clazz(Foo.Interaction.class), not(isPresent()));
    assertThat(inspector.clazz(Foo.Request.class), not(isPresent()));
  }

  private void checkKeepClassMembers(CodeInspector inspector) {
    assertThat(inspector.clazz(Main.class), isPresent());
    for (Class clazz : new Class[] {Foo.class, Foo.Interaction.class, Foo.Request.class}) {
      ClassSubject cls = inspector.clazz(clazz);
      assertThat(cls, isPresent());
      assertEquals(1, cls.asFoundClassSubject().allFields().size());
      cls.forAllFields(field -> assertThat(field, not(isRenamed())));
    }
  }

  private void checkKeepClassMembersRenamed(CodeInspector inspector) {
    assertThat(inspector.clazz(Main.class), isPresent());
    for (Class clazz : new Class[] {Foo.class, Foo.Interaction.class, Foo.Request.class}) {
      ClassSubject cls = inspector.clazz(clazz);
      assertThat(cls, isPresent());
      assertThat(cls, isRenamed());
      assertEquals(1, cls.asFoundClassSubject().allFields().size());
      cls.forAllFields(field -> assertThat(field, isRenamed()));
    }
  }

  @Test
  public void testNoDependentRules() throws Exception {
    runTest("", this::checkNoKeepClassMembers);
  }

  @Test
  public void testDependentWithKeepClass() throws Exception {
    runTest(
        "-keep @" + pkg + ".JsonClass class ** { <fields>; }",
        this::checkKeepClassMembers);
  }

  @Test
  public void testDependentWithKeepClassAllowObfuscation() throws Exception {
    runTest(
        "-keep,allowobfuscation @" + pkg + ".JsonClass class ** { <fields>; }",
        this::checkKeepClassMembersRenamed);
  }

  @Test
  public void testDependentWithKeepClassMembers() throws Exception {
    runTest(
        "-keepclassmembers @" + pkg + ".JsonClass class ** { <fields>; }",
        this::checkKeepClassMembers);
  }

  @Test
  public void testDependentWithKeepClassMembersAllowObfuscation() throws Exception {
    runTest(
        "-keepclassmembers,allowobfuscation @" + pkg + ".JsonClass class ** { <fields>; }",
        this::checkKeepClassMembersRenamed);
  }

  @Test
  public void testDependentWithIfKeepClassMembers() throws Exception {
    runTest(
        "-if @" + pkg + ".JsonClass class * -keepclassmembers class <1> { <fields>; }",
        this::checkKeepClassMembers);
  }

  @Test
  public void testDependentWithIfKeepClassMembersAllowObfuscation() throws Exception {
    runTest(
        "-if @"
            + pkg
            + ".JsonClass class * -keepclassmembers,allowobfuscation class <1> { <fields>; }",
        this::checkKeepClassMembersRenamed);
  }

  @Test
  public void testDependentWithIfKeep() throws Exception {
    runTest(
        "-if @" + pkg + ".JsonClass class * -keep class <1> { <fields>; }",
        this::checkKeepClassMembers);
  }

  @Test
  public void testDependentWithIfKeepAllowObfuscation() throws Exception {
    runTest(
        "-if @" + pkg + ".JsonClass class * -keep,allowobfuscation class <1> { <fields>; }",
        this::checkKeepClassMembersRenamed);
  }
}
