// 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.classmerging.horizontal;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestParameters;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.codeinspector.VerticallyMergedClassesInspector;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Test;

public class JavaLambdaMergingTest extends HorizontalClassMergingTestBase {

  public JavaLambdaMergingTest(TestParameters parameters, boolean enableHorizontalClassMerging) {
    super(parameters, enableHorizontalClassMerging);
  }

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(getClass())
        .addKeepMainRule(Main.class)
        .addOptionsModification(
            options -> {
              options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging);
              assertFalse(options.horizontalClassMergerOptions().isJavaLambdaMergingEnabled());
              options.horizontalClassMergerOptions().enableJavaLambdaMerging();
            })
        .addHorizontallyMergedClassesInspectorIf(
            enableHorizontalClassMerging && parameters.isDexRuntime(),
            inspector -> {
              Set<DexType> lambdaSources =
                  inspector.getSources().stream()
                      .filter(JavaLambdaMergingTest::isLambda)
                      .collect(Collectors.toSet());
              assertEquals(3, lambdaSources.size());
              DexType firstTarget = inspector.getTarget(lambdaSources.iterator().next());
              for (DexType lambdaSource : lambdaSources) {
                assertTrue(isLambda(inspector.getTarget(lambdaSource)));
                assertEquals(firstTarget, inspector.getTarget(lambdaSource));
              }
            })
        .addVerticallyMergedClassesInspector(
            VerticallyMergedClassesInspector::assertNoClassesMerged)
        .setMinApi(parameters.getApiLevel())
        .compile()
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines("Hello world!");
  }

  private static boolean isLambda(DexType type) {
    return SyntheticItemsTestUtils.isInternalLambda(
        Reference.classFromDescriptor(type.toDescriptorString()));
  }

  public static class Main {

    public static void main(String[] args) {
      HelloGreeter helloGreeter =
          System.currentTimeMillis() > 0
              ? () -> System.out.print("Hello")
              : () -> {
                throw new RuntimeException();
              };
      WorldGreeter worldGreeter =
          System.currentTimeMillis() > 0
              ? () -> System.out.println(" world!")
              : () -> {
                throw new RuntimeException();
              };
      helloGreeter.hello();
      worldGreeter.world();
    }
  }

  interface HelloGreeter {

    void hello();
  }

  interface WorldGreeter {

    void world();
  }
}
