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

import static org.hamcrest.CoreMatchers.containsString;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.google.common.collect.ImmutableList;
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 MissingInterfaceTest extends TestBase {

  private final TestParameters parameters;
  private final String[] EXPECTED = new String[] {"B112849320", "8"};

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

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

  @Test
  public void test_missingInterface() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(TestClassForB112849320.class)
        .addDontWarn(GoingToBeMissed.class)
        .setMinApi(parameters.getApiLevel())
        .addKeepMainRule(TestClassForB112849320.class)
        .addOptionsModification(options -> options.enableInlining = false)
        .compile()
        .addRunClasspathFiles(
            buildOnDexRuntime(
                parameters,
                writeToJar(ImmutableList.of(ToolHelper.getClassAsBytes(GoingToBeMissed.class)))))
        .run(parameters.getRuntime(), TestClassForB112849320.class)
        .forCfRuntime(r -> r.assertSuccessWithOutputLines(EXPECTED))
        .otherwise(
            r -> {
              r.assertStdoutMatches(containsString("B112849320"));
              r.assertFailureWithErrorThatThrows(AbstractMethodError.class);
            });
  }


  @Test
  public void test_passingInterfaceAsLib() throws Exception {
    Path lib = writeToJar(ImmutableList.of(ToolHelper.getClassAsBytes(GoingToBeMissed.class)));
    testForR8(parameters.getBackend())
        .addProgramClasses(TestClassForB112849320.class)
        .addLibraryFiles(lib)
        .addDefaultRuntimeLibrary(parameters)
        .setMinApi(parameters.getApiLevel())
        .addKeepMainRule(TestClassForB112849320.class)
        .addOptionsModification(options -> options.enableInlining = false)
        .addRunClasspathFiles(buildOnDexRuntime(parameters, lib))
        .run(parameters.getRuntime(), TestClassForB112849320.class)
        .assertSuccessWithOutputLines(EXPECTED);
  }

  interface GoingToBeMissed {
    void onSomeEvent(long soLong);
  }

  public static class TestClassForB112849320 {
    GoingToBeMissed instance;

    void foo(GoingToBeMissed instance) {
      System.out.println("B112849320");
      this.instance = instance;
    }

    void bar() {
      instance.onSomeEvent(8L);
    }

    public static void main(String[] args) {
      TestClassForB112849320 self = new TestClassForB112849320();
      self.foo(
          l -> {
            if (l > 0) {
              System.out.println(l);
            }
          });
      self.bar();
    }
  }
}
