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

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.CompilationFailedException;
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.TestParameters;
import com.android.tools.r8.utils.BooleanUtils;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
 * This test is changed based on the discussion in b/139794417 to not include overridden members
 * which is compatible with -whyareyoukeeping.
 */
@RunWith(Parameterized.class)
public class CheckDiscardedOverriddenMethodTest extends TestBase {

  @Parameters(name = "{0} minification: {1}")
  public static Collection<Object[]> data() {
    return buildParameters(getTestParameters().withNoneRuntime().build(), BooleanUtils.values());
  }

  private final TestParameters parameters;
  private final boolean minification;

  public CheckDiscardedOverriddenMethodTest(TestParameters parameters, boolean minification) {
    this.parameters = parameters;
    this.minification = minification;
  }

  private void test(Class<?> main, Class<?> targetClass) throws Exception {
    try {
      testForR8(Backend.DEX)
          .addInnerClasses(CheckDiscardedOverriddenMethodTest.class)
          .addKeepMainRule(main)
          .addKeepRules(
              "-checkdiscard class **.*$" + targetClass.getSimpleName() + " { void gone(); }")
          .enableClassInliningAnnotations()
          .enableInliningAnnotations()
          .enableMergeAnnotations()
          .minification(minification)
          .setMinApi(parameters.getRuntime())
          // Asserting that -checkdiscard is not giving any information out on an un-removed
          // sub-type member.
          .compileWithExpectedDiagnostics(diagnostics -> diagnostics.assertInfosCount(0));
    } catch (CompilationFailedException e) {
      String message = e.getCause().getMessage();
      assertThat(message, containsString("Discard checks failed."));
    }
  }

  @Test
  public void testExtends() throws Exception {
    test(TestMain1.class, Base.class);
  }

  @Test
  public void testImplements() throws Exception {
    test(TestMain2.class, Itf.class);
  }

  @NeverMerge
  static class Base {
    @NeverInline
    void gone() {
      System.out.println("should be gone");
    }
  }

  @NeverClassInline
  static class Sub extends Base {
    @NeverInline
    @Override
    void gone() {
      System.out.println("used");
    }
  }

  static class TestMain1 {
    public static void main(String... args) {
      new Sub().gone();
    }
  }

  @NeverMerge
  interface Itf {
    void gone();
  }

  @NeverClassInline
  static class Impl implements Itf {
    @NeverInline
    @Override
    public void gone() {
      System.out.println("used");
    }
  }

  static class TestMain2 {
    public static void main(String... args) {
      new Impl().gone();
    }
  }
}
