// 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.ir.optimize.extrasubclasses;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.NeverClassInline;
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 com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.nio.file.Path;
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 InterfaceAlsoImplementedByMissingClassTest extends TestBase {

  private final TestParameters parameters;

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

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

  /**
   * Tests that it is possible to provide an implementation of an interface after the program has
   * been compiled with R8, as long as the interface and its methods have been kept.
   */
  @Test
  public void test() throws Exception {
    Path r8Out =
        testForR8(parameters.getBackend())
            // B is not visible to the R8 compilation.
            .addProgramClasses(TestClass.class, I.class, A.class)
            // Helper is added on the classpath such that R8 doesn't know what it does.
            .addClasspathClasses(Helper.class)
            .addKeepMainRule(TestClass.class)
            // Keeping I and I.kept() should make it possible to provide an implementation of
            // I after the R8 compilation.
            .addKeepRules("-keep class " + I.class.getTypeName() + " { void kept(); }")
            .enableNeverClassInliningAnnotations()
            .setMinApi(parameters.getApiLevel())
            .compile()
            .inspect(this::inspect)
            .writeToZip();

    testForRuntime(parameters)
        .addProgramClasses(B.class, Helper.class)
        .addRunClasspathFiles(r8Out)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("Hello world!", "The end");
  }

  private void inspect(CodeInspector inspector) {
    ClassSubject iClassSubject = inspector.clazz(I.class);
    assertThat(iClassSubject.uniqueMethodWithName("kept"), isPresent());

    ClassSubject aClassSubject = inspector.clazz(A.class);
    assertThat(aClassSubject.uniqueMethodWithName("kept"), isPresent());

    // I.notKept() and A.notKept() should not be present, because the only invoke instruction
    // targeting I.notKept() should have been inlined.
    assertThat(iClassSubject.uniqueMethodWithName("notKept"), not(isPresent()));
    assertThat(aClassSubject.uniqueMethodWithName("notKept"), not(isPresent()));
  }

  static class TestClass {

    public static void main(String[] args) {
      // Casting `notAlwaysA` to A and invoking A.kept() would lead to a ClassCastException.
      I notAlwaysA = System.currentTimeMillis() >= 0 ? Helper.getInstance() : new A();
      notAlwaysA.kept();

      // We should be able to inline I.notKept() when the receiver is guaranteed to be A.
      I alwaysA = new A();
      alwaysA.notKept();

      System.out.println("The end");
    }
  }

  interface I {

    void kept();

    void notKept();
  }

  @NeverClassInline
  static class A implements I {

    @Override
    public void kept() {
      throw new RuntimeException();
    }

    @Override
    public void notKept() {
      System.out.println(" world!");
    }
  }

  // Only declarations are visible via the classpath.
  static class Helper {

    static I getInstance() {
      return new B();
    }
  }

  // Not visible during the R8 compilation.
  static class B implements I {

    @Override
    public void kept() {
      System.out.print("Hello");
    }

    @Override
    public void notKept() {
      throw new RuntimeException();
    }
  }
}
