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

import static com.android.tools.r8.ToolHelper.getKotlinCompilers;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler;
import com.android.tools.r8.TestShrinkerBuilder;
import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class KotlinUnusedArgumentsInLambdasTest extends AbstractR8KotlinTestBase {

  @Parameterized.Parameters(name = "target: {0}, kotlinc: {1}, allowAccessModification: {2}")
  public static Collection<Object[]> data() {
    return buildParameters(
        KotlinTargetVersion.values(), getKotlinCompilers(), BooleanUtils.values());
  }

  public KotlinUnusedArgumentsInLambdasTest(
      KotlinTargetVersion targetVersion, KotlinCompiler kotlinc, boolean allowAccessModification) {
    super(targetVersion, kotlinc, allowAccessModification);
  }

  @Test
  public void testMergingKStyleLambdasAfterUnusedArgumentRemoval() throws Exception {
    final String mainClassName = "unused_arg_in_lambdas_kstyle.MainKt";
    runTest(
            "unused_arg_in_lambdas_kstyle",
            mainClassName,
            TestShrinkerBuilder::addDontWarnJetBrainsAnnotations)
        .inspect(
            inspector ->
                inspector.forAllClasses(
                    classSubject -> {
                      if (classSubject.getOriginalDescriptor().contains("$ks")) {
                        MethodSubject init = classSubject.init(ImmutableList.of("int"));
                        assertThat(init, isPresent());
                        // Arity 2 should appear.
                        assertTrue(init.iterateInstructions(i -> i.isConstNumber(2)).hasNext());

                        MethodSubject invoke = classSubject.uniqueMethodWithName("invoke");
                        assertThat(invoke, isPresent());
                        assertEquals(2, invoke.getMethod().method.proto.parameters.size());
                      }
                    }));
  }

  @Test
  public void testMergingJStyleLambdasAfterUnusedArgumentRemoval() throws Exception {
    final String mainClassName = "unused_arg_in_lambdas_jstyle.MainKt";
    runTest(
            "unused_arg_in_lambdas_jstyle",
            mainClassName,
            TestShrinkerBuilder::addDontWarnJetBrainsAnnotations)
        .inspect(
            inspector ->
                inspector.forAllClasses(
                    classSubject -> {
                      if (classSubject.getOriginalDescriptor().contains("$js")) {
                        MethodSubject get = classSubject.uniqueMethodWithName("get");
                        assertThat(get, isPresent());
                        assertEquals(3, get.getMethod().method.proto.parameters.size());
                      }
                    }));
  }
}
