// Copyright (c) 2020, 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 com.android.tools.r8.CollectorsUtils.toSingle;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.NoVerticalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.shaking.Enqueuer.Mode;
import com.android.tools.r8.utils.OptionalBool;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  private final TestParameters parameters;

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

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

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(LibraryMethodOverrideInLambdaMarkingTest.class)
        .addKeepMainRule(TestClass.class)
        .addOptionsModification(
            options -> options.testing.enqueuerInspector = this::verifyLibraryOverrideInformation)
        .enableNoVerticalClassMergingAnnotations()
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("null", "null");
  }

  private void verifyLibraryOverrideInformation(AppInfoWithLiveness appInfo, Mode mode) {
    DexItemFactory dexItemFactory = appInfo.dexItemFactory();
    verifyIteratorMethodMarkedAsOverridingLibraryMethod(
        appInfo, dexItemFactory.createType(descriptor(I.class)), OptionalBool.FALSE);
    verifyIteratorMethodMarkedAsOverridingLibraryMethod(
        appInfo, dexItemFactory.createType(descriptor(J.class)), OptionalBool.FALSE);
    if (parameters.isDexRuntime()) {
      DexProgramClass lambda =
          appInfo.classes().stream()
              .filter(x -> x.toSourceString().contains("$InternalSyntheticLambda"))
              .collect(toSingle());
      verifyIteratorMethodMarkedAsOverridingLibraryMethod(
          appInfo, lambda.getType(), OptionalBool.TRUE);
    }
  }

  private void verifyIteratorMethodMarkedAsOverridingLibraryMethod(
      AppInfoWithLiveness appInfo, DexType type, OptionalBool expected) {
    DexProgramClass clazz = appInfo.definitionFor(type).asProgramClass();
    DexEncodedMethod method =
        clazz.lookupVirtualMethod(m -> m.getReference().name.toString().equals("iterator"));
    // TODO(b/149976493): Mark library overrides from lambda instances.
    if (parameters.isCfRuntime()) {
      assertEquals(OptionalBool.FALSE, method.isLibraryMethodOverride());
    } else {
      assertEquals(expected, method.isLibraryMethodOverride());
    }
  }

  static class TestClass {

    public static void onI(I i) {
      System.out.println(i.iterator());
    }

    public static void onJ(J j) {
      System.out.println(j.iterator());
    }

    public static void main(String[] args) {
      Object f = ((I & J) () -> null);
      onI((I) f);
      onJ((J) f);
    }
  }

  @NoVerticalClassMerging
  interface I {

    Iterator<Object> iterator();
  }

  @NoVerticalClassMerging
  interface J extends Iterable<Object> {

    @Override
    Iterator<Object> iterator();

    @Override
    default void forEach(Consumer<? super Object> action) {
      // Intentionally empty.
    }

    @Override
    default Spliterator<Object> spliterator() {
      return null;
    }
  }
}
