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

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class ProgramInterfaceNotImplementedTest extends TestBase {

  private final TestParameters parameters;

  public interface I {

    Object foo();
  }

  public abstract static class A implements I {

    @Override
    public abstract Object foo();
  }

  public abstract static class B implements I {

    @Override
    public Object foo() {
      return "FOO";
    }
  }

  public static class C implements I {

    @Override
    public Object foo() {
      return "FOO";
    }
  }

  public abstract static class Lib {
    public abstract Object foo();
  }

  public static class D extends Lib implements I {

    @Override
    public Object foo() {
      return "FOO";
    }
  }

  public static class MainA {

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

  public static class MainB {

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

  public static class MainC {

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

  public static class MainD {

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

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withAllRuntimes().build();
  }

  public ProgramInterfaceNotImplementedTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  @Test
  public void testRemovingMethodInA()
      throws ExecutionException, CompilationFailedException, IOException {
    test(A.class, MainA.class);
  }

  @Test
  public void testRemovingMethodInB()
      throws ExecutionException, CompilationFailedException, IOException {
    test(B.class, MainB.class);
  }

  @Test
  public void testRemovingMethodInC()
      throws ExecutionException, CompilationFailedException, IOException {
    test(C.class, MainC.class);
  }

  private void test(Class<?> clazz, Class<?> main)
      throws ExecutionException, CompilationFailedException, IOException {
    testForR8(parameters.getBackend())
        .addProgramClasses(I.class, clazz, main)
        .addKeepClassAndMembersRules(I.class)
        .addKeepMainRule(main)
        .noMinification()
        .setMinApi(parameters.getRuntime())
        .run(parameters.getRuntime(), main)
        .assertSuccessWithOutputThatMatches(containsString(clazz.getTypeName()))
        .inspect(
            codeInspector -> {
              ClassSubject foundClazz = codeInspector.clazz(clazz);
              assertThat(foundClazz, isPresent());
              assertTrue(foundClazz.allMethods().isEmpty());
            });
  }

  @Test
  public void testRemovingMethodInD()
      throws ExecutionException, CompilationFailedException, IOException {
    R8TestCompileResult library =
        testForR8(parameters.getBackend())
            .addProgramClasses(Lib.class)
            .addKeepAllClassesRule()
            .setMinApi(parameters.getRuntime())
            .compile();
    testForR8(parameters.getBackend())
        .addProgramClasses(I.class, D.class, MainD.class)
        .addLibraryClasses(Lib.class)
        .addLibraryFiles(runtimeJar(parameters.getBackend()))
        .addKeepClassAndMembersRules(I.class)
        .addKeepMainRule(MainD.class)
        .setMinApi(parameters.getRuntime())
        .noMinification()
        .compile()
        .addRunClasspathFiles(library.writeToZip())
        .run(parameters.getRuntime(), MainD.class)
        .assertSuccessWithOutputThatMatches(containsString(D.class.getTypeName()));
  }
}
