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

import static com.android.tools.r8.ToolHelper.EXAMPLES_KOTLIN_RESOURCE_DIR;
import static com.android.tools.r8.kotlin.KotlinLambdaMergingTest.kstyle;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.kotlin.KotlinLambdaMergingTest.Group;
import com.android.tools.r8.kotlin.KotlinLambdaMergingTest.Lambda;
import com.android.tools.r8.kotlin.KotlinLambdaMergingTest.Verifier;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.junit.Test;

public class KotlinxMetadataExtensionsServiceTest extends TestBase {

  private void forkR8_kstyle_trivial(boolean allowAccessModification) throws Exception {
    if (!isRunR8Jar()) {
      return;
    }
    Path working = temp.getRoot().toPath();
    Path kotlinJar =
        Paths.get(EXAMPLES_KOTLIN_RESOURCE_DIR, "JAVA_8", "lambdas_kstyle_trivial.jar")
            .toAbsolutePath();
    Path output = working.resolve("classes.dex");
    assertFalse(Files.exists(output));
    Path proguardConfiguration = temp.newFile("test.conf").toPath();
    List<String> lines = ImmutableList.of(
        "-keepattributes Signature,InnerClasses,EnclosingMethod",
        "-keep class **MainKt {",
        "  public static void main(...);",
        "}",
        "-printmapping",
        "-dontobfuscate",
        allowAccessModification ? "-allowaccessmodification" : ""
    );
    FileUtils.writeTextFile(proguardConfiguration, lines);
    ProcessResult result = ToolHelper.forkR8Jar(working,
        "--pg-conf", proguardConfiguration.toString(),
        "--lib", ToolHelper.getAndroidJar(AndroidApiLevel.O).toAbsolutePath().toString(),
        kotlinJar.toString());
    assertEquals(0, result.exitCode);
    assertThat(result.stderr, not(containsString(
        "No MetadataExtensions instances found in the classpath")));
    assertTrue(Files.exists(output));

    CodeInspector inspector = new CodeInspector(output);
    Verifier verifier = new Verifier(inspector);
    String pkg = "lambdas_kstyle_trivial";
    verifier.assertLambdaGroups(
        allowAccessModification
            ? new Group[] {
              kstyle("", 0, 4),
              kstyle("", 1, 9),
              kstyle("", 2, 2), // -\
              kstyle("", 2, 5), // - 3 groups different by main method
              kstyle("", 2, 4), // -/
              kstyle("", 3, 2),
              kstyle("", 22, 2)
            }
            : new Group[] {
              kstyle(pkg, 0, 2),
              kstyle(pkg, 1, 5),
              kstyle(pkg, 2, 5), // - 2 groups different by main method
              kstyle(pkg, 2, 4), // -/
              kstyle(pkg, 3, 2),
              kstyle(pkg, 22, 2),
              kstyle(pkg + "/inner", 0, 2),
              kstyle(pkg + "/inner", 1, 4)
            });

    verifier.assertLambdas(
        allowAccessModification
            ? new Lambda[] {}
            : new Lambda[] {
              new Lambda(pkg, "MainKt$testStateless$8", 2),
              new Lambda(pkg + "/inner", "InnerKt$testInnerStateless$7", 2)
            });
  }

  @Test
  public void testTrivialKs_allowAccessModification() throws Exception {
    forkR8_kstyle_trivial(true);
  }

  @Test
  public void testTrivialKs_notAllowAccessModification() throws Exception {
    forkR8_kstyle_trivial(false);
  }

}
