// 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().withDexRuntimes().withAllApiLevels().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.inlinerOptions().enableInlining = false)
        .addKeepPackageNamesRule(GoingToBeMissed.class.getPackage())
        .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.inlinerOptions().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();
    }
  }
}
