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

import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileNameAndLineNumber;
import static junit.framework.TestCase.assertEquals;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.SourceFileEnvironment;
import com.android.tools.r8.SourceFileProvider;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.graph.DexDebugEntry;
import com.android.tools.r8.graph.DexDebugEntryBuilder;
import com.android.tools.r8.naming.retrace.StackTrace;
import com.android.tools.r8.naming.retrace.StackTrace.StackTraceLine;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
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 EnsureNoDebugInfoEmittedForPcOnlyTestRunner extends TestBase {

  private static final String FILENAME_MAIN = "EnsureNoDebugInfoEmittedForPcOnlyTest.java";
  private static final Class<?> MAIN = EnsureNoDebugInfoEmittedForPcOnlyTest.class;

  private final TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withDexRuntimes().withAllApiLevels().build();
  }

  public EnsureNoDebugInfoEmittedForPcOnlyTestRunner(TestParameters parameters) {
    this.parameters = parameters;
  }

  private boolean apiLevelSupportsPcAndSourceFileOutput() {
    // TODO(b/146565491): Update with API level once fixed.
    return false;
  }

  @Test
  public void testD8Debug() throws Exception {
    testForD8(parameters.getBackend())
        .debug()
        .addProgramClasses(MAIN)
        .setMinApi(parameters)
        .internalEnableMappingOutput()
        .run(parameters.getRuntime(), MAIN)
        // For a debug build we always expect the output to have actual line information.
        .inspectFailure(this::checkHasLineNumberInfo)
        .inspectStackTrace(this::checkExpectedStackTrace);
  }

  @Test
  public void testD8Release() throws Exception {
    testForD8(parameters.getBackend())
        .release()
        .addProgramClasses(MAIN)
        .setMinApi(parameters)
        .internalEnableMappingOutput()
        .applyIf(
            apiLevelSupportsPcAndSourceFileOutput(),
            builder ->
                builder.addOptionsModification(
                    options -> {
                      options.sourceFileProvider =
                          new SourceFileProvider() {
                            @Override
                            public String get(SourceFileEnvironment environment) {
                              return null;
                            }

                            @Override
                            public boolean allowDiscardingSourceFile() {
                              return true;
                            }
                          };
                    }))
        .run(parameters.getRuntime(), MAIN)
        .inspectFailure(
            inspector -> {
              if (apiLevelSupportsPcAndSourceFileOutput()) {
                checkNoDebugInfo(inspector, 5);
              } else {
                checkHasLineNumberInfo(inspector);
              }
            })
        .inspectStackTrace(this::checkExpectedStackTrace);
  }

  @Test
  public void testD8ReleaseWithoutMapOutput() throws Exception {
    testForD8(parameters.getBackend())
        .release()
        .addProgramClasses(MAIN)
        .setMinApi(parameters)
        .run(parameters.getRuntime(), MAIN)
        // If compiling without a map output actual debug info should also be retained. Otherwise
        // there would not be any way to obtain the actual lines.
        .inspectFailure(this::checkHasLineNumberInfo)
        .inspectStackTrace(this::checkExpectedStackTrace);
  }

  @Test
  public void testNoEmittedDebugInfoR8() throws Exception {
    assumeTrue(apiLevelSupportsPcAndSourceFileOutput());
    testForR8(parameters.getBackend())
        .addProgramClasses(MAIN)
        .addKeepMainRule(MAIN)
        .addKeepAttributeLineNumberTable()
        .setMinApi(parameters)
        .run(parameters.getRuntime(), MAIN)
        .inspectOriginalStackTrace(
            (stackTrace, inspector) -> {
              assertEquals(MAIN.getTypeName(), stackTrace.get(0).className);
              assertEquals("main", stackTrace.get(0).methodName);
              checkNoDebugInfo(inspector, 1);
            })
        .inspectStackTrace(this::checkExpectedStackTrace);
  }

  private void checkNoDebugInfo(CodeInspector inspector, int expectedMethodsInMain) {
    ClassSubject clazz = inspector.clazz(MAIN);
    assertEquals(expectedMethodsInMain, clazz.allMethods().size());
    MethodSubject main = clazz.uniqueMethodWithOriginalName("main");
    assertNull(main.getMethod().getCode().asDexCode().getDebugInfo());
  }

  private void checkHasLineNumberInfo(CodeInspector inspector) {
    ClassSubject clazz = inspector.clazz(MAIN);
    MethodSubject main = clazz.uniqueMethodWithOriginalName("main");
    List<DexDebugEntry> entries =
        new DexDebugEntryBuilder(main.getMethod(), inspector.getFactory()).build();
    Set<Integer> lines =
        entries.stream().map(e -> e.getPosition().getLine()).collect(Collectors.toSet());
    assertFalse(lines.isEmpty());
  }

  private void checkExpectedStackTrace(StackTrace stackTrace) {
    assertThat(
        stackTrace,
        isSameExceptForFileNameAndLineNumber(
            StackTrace.builder()
                .add(line("a", 11))
                .add(line("b", 18))
                .add(line("main", 23))
                .build()));
  }

  private StackTraceLine line(String method, int line) {
    return StackTraceLine.builder()
        .setClassName(MAIN.getTypeName())
        .setMethodName(method)
        .setLineNumber(line)
        .setFileName(FILENAME_MAIN)
        .build();
  }
}
