// 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.methods.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.methods.MethodsTestBase;
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.google.common.collect.ImmutableSet;
import java.util.Collection;
import java.util.Set;
import org.junit.Test;

@NeverMerge
class Super {
  private void m1() {}
}

@NeverMerge
class Sub extends Super {
  private void m2() {}
}

@NeverMerge
class SubSub extends Sub {
  private void m3() {}
}

class Main {

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

  public static void main(String[] args) {
    printMethod(Super.class, "m1");
    printMethod(Sub.class, "m2");
    printMethod(SubSub.class, "m3");
  }
}

public class PrivateMethodsTest extends MethodsTestBase {

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

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

  private void checkMethods(CodeInspector inspector, Shrinker shrinker, Set<String> expected) {
    ClassSubject superSubject = inspector.clazz(Super.class);
    assertThat(superSubject, isPresent());
    assertEquals(
        shrinker != Shrinker.R8Full && expected.contains("m1"),
        superSubject.uniqueMethodWithName("m1").isPresent());
    ClassSubject subSubject = inspector.clazz(Sub.class);
    assertThat(subSubject, isPresent());
    assertEquals(
        shrinker != Shrinker.R8Full && expected.contains("m2"),
        subSubject.uniqueMethodWithName("m2").isPresent());
    ClassSubject subSubSubject = inspector.clazz(SubSub.class);
    assertThat(subSubSubject, isPresent());
    assertEquals(expected.contains("m3"), subSubSubject.uniqueMethodWithName("m3").isPresent());
  }

  public String allMethodsOutput(Shrinker shrinker) {
    if (shrinker != Shrinker.R8Full) {
      return StringUtils.lines("Super.m1 found", "Sub.m2 found", "SubSub.m3 found");
    } else {
      return StringUtils.lines("Super.m1 not found", "Sub.m2 not found", "SubSub.m3 found");
    }
  }

  public String onlyM1Output(Shrinker shrinker) {
    if (shrinker != Shrinker.R8Full) {
      return StringUtils.lines("Super.m1 found", "Sub.m2 not found", "SubSub.m3 not found");
    } else {
      return StringUtils.lines("Super.m1 not found", "Sub.m2 not found", "SubSub.m3 not found");
    }
  }

  public String onlyM2Output(Shrinker shrinker) {
    if (shrinker != Shrinker.R8Full) {
      return StringUtils.lines("Super.m1 not found", "Sub.m2 found", "SubSub.m3 not found");
    } else {
      return StringUtils.lines("Super.m1 not found", "Sub.m2 not found", "SubSub.m3 not found");
    }
  }

  private void checkAllMethods(CodeInspector inspector, Shrinker shrinker) {
    checkMethods(inspector, shrinker, ImmutableSet.of("m1", "m2", "m3"));
  }

  private void checkOnlyM1(CodeInspector inspector, Shrinker shrinker) {
    checkMethods(inspector, shrinker, ImmutableSet.of("m1"));
  }

  private void checkOnlyM2(CodeInspector inspector, Shrinker shrinker) {
    checkMethods(inspector, shrinker, ImmutableSet.of("m2"));
  }

  private void checkOnlyM3(CodeInspector inspector, Shrinker shrinker) {
    checkMethods(inspector, shrinker, ImmutableSet.of("m3"));
  }

  @Test
  public void testKeepAllMethodsWithWildcard() throws Throwable {
    runTest("-keep class **.SubSub { *; }", this::checkAllMethods, this::allMethodsOutput);
  }

  @Test
  public void testKeepAllMethodsWithNameWildcard() throws Throwable {
    runTest("-keep class **.SubSub { void m*(); }", this::checkAllMethods, this::allMethodsOutput);
  }

  @Test
  public void testKeepAllMethodsWithMethods() throws Throwable {
    runTest("-keep class **.SubSub { <methods>; }", this::checkAllMethods, this::allMethodsOutput);
  }

  @Test
  public void testKeepM1() throws Throwable {
    runTest("-keep class **.SubSub { void m1(); }", this::checkOnlyM1, this::onlyM1Output);
  }

  @Test
  public void testKeepM2() throws Throwable {
    runTest("-keep class **.SubSub { void m2(); }", this::checkOnlyM2, this::onlyM2Output);
  }

  @Test
  public void testKeepM3() throws Throwable {
    runTest("-keep class **.SubSub { void m3(); }", this::checkOnlyM3, onlyM3Output());
  }

  @Test
  public void testKeepM1WithExtends() throws Throwable {
    runTest("-keep class * extends **.Sub { void m1(); }", this::checkOnlyM1, this::onlyM1Output);
  }

  @Test
  public void testKeepM2WithExtends() throws Throwable {
    runTest("-keep class * extends **.Sub { void m2(); }", this::checkOnlyM2, this::onlyM2Output);
  }

  @Test
  public void testKeepM3WithExtends() throws Throwable {
    runTest("-keep class * extends **.Sub { void m3(); }", this::checkOnlyM3, onlyM3Output());
  }
}
