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

import static com.android.tools.r8.utils.codeinspector.Matchers.containsLinePositions;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static junit.framework.TestCase.assertEquals;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8TestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.naming.retrace.StackTrace;
import com.android.tools.r8.naming.testclasses.ClassToBeMinified;
import com.android.tools.r8.naming.testclasses.Main;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.shaking.ProguardKeepAttributes;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.Matchers.LinePosition;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

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

  private static final String FILENAME_RENAME = "FOO";
  private static final String FILENAME_MAIN = "Main.java";
  private static final String FILENAME_CLASS_TO_BE_MINIFIED = "ClassToBeMinified.java";

  private final TestParameters parameters;
  private final boolean isCompat;
  private final boolean keepSourceFile;

  @Parameters(name = "{0}, is compat: {1}, keep source file attribute: {2}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(),
        BooleanUtils.values(),
        BooleanUtils.values());
  }

  public RenameSourceFileRetraceTest(
      TestParameters parameters, Boolean isCompat, Boolean keepSourceFile) {
    this.parameters = parameters;
    this.isCompat = isCompat;
    this.keepSourceFile = keepSourceFile;
  }

  @Test
  public void testR8()
      throws ExecutionException, CompilationFailedException, IOException, NoSuchMethodException {
    R8TestBuilder<? extends R8TestBuilder<?>> r8TestBuilder =
        isCompat ? testForR8Compat(parameters.getBackend()) : testForR8(parameters.getBackend());
    if (keepSourceFile) {
      r8TestBuilder.addKeepAttributes(ProguardKeepAttributes.SOURCE_FILE);
    }
    String minifiedFileName =
        (keepSourceFile && isCompat) ? FILENAME_CLASS_TO_BE_MINIFIED : getDefaultExpectedName();
    String mainFileName = keepSourceFile ? FILENAME_MAIN : getDefaultExpectedName();
    r8TestBuilder
        .addProgramClasses(ClassToBeMinified.class, Main.class)
        .addKeepAttributes(ProguardKeepAttributes.LINE_NUMBER_TABLE)
        .addKeepMainRule(Main.class)
        .setMinApi(parameters.getApiLevel())
        .enableInliningAnnotations()
        .run(parameters.getRuntime(), Main.class)
        .assertFailureWithErrorThatMatches(containsString("ClassToBeMinified.foo()"))
        .inspectFailure(inspector -> inspectOutput(inspector, minifiedFileName, mainFileName))
        .inspectStackTrace(stackTrace -> inspectStackTrace(stackTrace, FILENAME_MAIN));
  }

  @Test
  public void testRenameSourceFileR8()
      throws ExecutionException, CompilationFailedException, IOException, NoSuchMethodException {
    R8TestBuilder<? extends R8TestBuilder<?>> r8TestBuilder =
        isCompat ? testForR8Compat(parameters.getBackend()) : testForR8(parameters.getBackend());
    if (keepSourceFile) {
      r8TestBuilder.addKeepAttributes(ProguardKeepAttributes.SOURCE_FILE);
    }
    String expectedName = getDefaultExpectedName(FILENAME_RENAME);
    r8TestBuilder
        .addProgramClasses(ClassToBeMinified.class, Main.class)
        .addKeepAttributes(ProguardKeepAttributes.LINE_NUMBER_TABLE)
        .addKeepRules("-renamesourcefileattribute " + FILENAME_RENAME)
        .addKeepMainRule(Main.class)
        .setMinApi(parameters.getApiLevel())
        .enableInliningAnnotations()
        .run(parameters.getRuntime(), Main.class)
        .assertFailureWithErrorThatMatches(containsString("ClassToBeMinified.foo()"))
        .inspectFailure(inspector -> inspectOutput(inspector, expectedName, expectedName))
        .inspectStackTrace(stackTrace -> inspectStackTrace(stackTrace, expectedName));
  }

  private String getDefaultExpectedName() {
    return getDefaultExpectedName(parameters.getBackend() == Backend.CF ? "SourceFile" : "");
  }

  private String getDefaultExpectedName(String name) {
    if (!isCompat && !keepSourceFile) {
      return null;
    } else {
      return name;
    }
  }

  private void inspectOutput(
      CodeInspector inspector, String classToBeMinifiedFilename, String mainClassFilename) {
    inspectSourceFileForClass(inspector, Main.class, mainClassFilename);
    inspectSourceFileForClass(inspector, ClassToBeMinified.class, classToBeMinifiedFilename);
  }

  private void inspectSourceFileForClass(CodeInspector inspector, Class<?> clazz, String expected) {
    ClassSubject classToBeMinifiedSubject = inspector.clazz(clazz);
    assertThat(classToBeMinifiedSubject, isPresent());
    DexClass dexClass = classToBeMinifiedSubject.getDexProgramClass();
    String actualString = dexClass.sourceFile == null ? null : dexClass.sourceFile.toString();
    assertEquals(expected, actualString);
  }

  private void inspectStackTrace(StackTrace stackTrace, String mainFileName)
      throws NoSuchMethodException {
    if (!keepSourceFile) {
      return;
    }
    assertEquals(2, stackTrace.getStackTraceLines().size());
    MethodReference classToBeMinifiedFoo =
        Reference.methodFromMethod(ClassToBeMinified.class.getDeclaredMethod("foo"));
    MethodReference mainMain =
        Reference.methodFromMethod(Main.class.getDeclaredMethod("main", String[].class));
    LinePosition expectedStack =
        LinePosition.stack(
            LinePosition.create(classToBeMinifiedFoo, 1, 13, FILENAME_CLASS_TO_BE_MINIFIED),
            LinePosition.create(mainMain, 1, 10, mainFileName));
    assertThat(stackTrace, containsLinePositions(expectedStack));
  }
}
