// Copyright (c) 2017, 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.debug;

import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase.MinifyMode;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

/** Tests renaming of class and method names and corresponding proguard map output. */
@RunWith(Parameterized.class)
public class MinificationTest extends DebugTestBase {

  private static final String SOURCE_FILE = "Minified.java";

  @Parameterized.Parameters(name = "minification: {0}, proguardMap: {1}")
  public static Collection minificationControl() {
    ImmutableList.Builder<Object> builder = ImmutableList.builder();
    for (MinifyMode mode : MinifyMode.values()) {
      builder.add((Object) new Object[]{mode, false});
      if (mode.isMinify()) {
        builder.add((Object) new Object[]{mode, true});
      }
    }
    return builder.build();
  }

  @Rule
  public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();

  private final MinifyMode minificationMode;
  private final boolean writeProguardMap;

  public MinificationTest(MinifyMode minificationMode, boolean writeProguardMap) throws Exception {
    this.minificationMode = minificationMode;
    this.writeProguardMap = writeProguardMap;
  }

  private boolean minifiedNames() {
    return minificationMode.isMinify() && !writeProguardMap;
  }

  private DebugTestConfig getTestConfig() throws Throwable {
    List<String> proguardConfigurations = Collections.emptyList();
    if (minificationMode.isMinify()) {
      ImmutableList.Builder<String> builder = ImmutableList.builder();
      builder.add("-keep public class Minified { public static void main(java.lang.String[]); }");
      builder.add("-keepattributes SourceFile");
      builder.add("-keepattributes LineNumberTable");
      if (minificationMode == MinifyMode.AGGRESSIVE) {
        builder.add("-overloadaggressively");
      }
      proguardConfigurations = builder.build();
    }

    int minSdk = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
    Path dexOutputDir = temp.newFolder().toPath();
    Path proguardMap = writeProguardMap ? dexOutputDir.resolve("proguard.map") : null;
    R8Command.Builder builder =
        R8Command.builder()
            .addProgramFiles(DEBUGGEE_JAR)
            .setOutput(dexOutputDir, OutputMode.DexIndexed)
            .setMinApiLevel(minSdk)
            .setMode(CompilationMode.DEBUG)
            .addLibraryFiles(ToolHelper.getAndroidJar(minSdk));
    if (proguardMap != null) {
      builder.setProguardMapOutputPath(proguardMap);
    }
    if (!proguardConfigurations.isEmpty()) {
      builder.addProguardConfiguration(proguardConfigurations, Origin.unknown());
    }
    // Disable line number optimization if we're not using a Proguard map.
    ToolHelper.runR8(
        builder.build(),
        proguardMap == null
            ? (oc -> oc.lineNumberOptimization = LineNumberOptimization.OFF)
            : null);

    DexDebugTestConfig config = new DexDebugTestConfig(dexOutputDir.resolve("classes.dex"));
    config.setProguardMap(proguardMap);
    return config;
  }

  @Test
  public void testBreakInMainClass() throws Throwable {
    final String className = "Minified";
    final String methodName = minifiedNames() ? "a" : "test";
    final String signature = "()V";
    final String innerClassName = minifiedNames() ? "a" : "Minified$Inner";
    final String innerMethodName = minifiedNames() ? "a" : "innerTest";
    final String innerSignature = "()I";
    runDebugTest(
        getTestConfig(),
        className,
        breakpoint(className, methodName, signature),
        run(),
        checkMethod(className, methodName, signature),
        checkLine(SOURCE_FILE, 14),
        stepOver(INTELLIJ_FILTER),
        checkMethod(className, methodName, signature),
        checkLine(SOURCE_FILE, 15),
        stepInto(INTELLIJ_FILTER),
        checkMethod(innerClassName, innerMethodName, innerSignature),
        checkLine(SOURCE_FILE, 8),
        run());
  }

  @Test
  public void testBreakInPossiblyRenamedClass() throws Throwable {
    final String className = "Minified";
    final String innerClassName = minifiedNames() ? "a" : "Minified$Inner";
    final String innerMethodName = minifiedNames() ? "a" : "innerTest";
    final String innerSignature = "()I";
    runDebugTest(
        getTestConfig(),
        className,
        breakpoint(innerClassName, innerMethodName, innerSignature),
        run(),
        checkMethod(innerClassName, innerMethodName, innerSignature),
        checkLine(SOURCE_FILE, 8),
        run());
  }
}
