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

import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.DebuggeeState;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.stream.Stream;
import org.junit.Assume;
import org.junit.Test;

public class NopDebugTestRunner extends DebugTestBase {

  private final Class<?> CLAZZ = NopTest.class;

  @Test
  public void testNop() throws Exception {
    // R8 will dead-code eliminate "args = args" in NopTest.
    // In debug mode the programmer should still be able to break on dead code,
    // so R8 inserts a NOP in the output. Test that CfNop.buildIR() works.
    runTwiceTest(writeInput(CLAZZ), CLAZZ.getName());
  }

  private Path writeInput(Class<?> clazz) throws Exception {
    Path inputJar = temp.getRoot().toPath().resolve("input.jar");
    ClassFileConsumer inputConsumer = new ClassFileConsumer.ArchiveConsumer(inputJar);
    String descriptor = DescriptorUtils.javaTypeToDescriptor(clazz.getName());
    inputConsumer.accept(ByteDataView.of(ToolHelper.getClassAsBytes(clazz)), descriptor, null);
    inputConsumer.finished(null);
    return inputJar;
  }

  private void runTwiceTest(Path inputJar, String mainClass) throws Exception {
    Path output1 = runR8(inputJar, "output1.jar");
    Path output2 = runR8(output1, "output2.jar");
    stepOutput(mainClass, inputJar, output1, output2);
  }

  private Path runR8(Path inputJar, String outputName) throws Exception {
    Path outputJar = temp.getRoot().toPath().resolve(outputName);
    ToolHelper.runR8(
        R8Command.builder()
            .addLibraryFiles(ToolHelper.getJava8RuntimeJar())
            .setMode(CompilationMode.DEBUG)
            .setDisableTreeShaking(true)
            .setDisableMinification(true)
            .addProguardConfiguration(
                ImmutableList.of("-keepattributes SourceFile,LineNumberTable"), Origin.unknown())
            .addProgramFiles(inputJar)
            .setOutput(outputJar, OutputMode.ClassFile)
            .build());
    return outputJar;
  }

  private void stepOutput(String mainClass, Path inputJar, Path output1, Path output2)
      throws Exception {
    Assume.assumeTrue(
        "Skipping test "
            + testName.getMethodName()
            + " because debug tests are not yet supported on Windows",
        !ToolHelper.isWindows());
    new DebugStreamComparator()
        .add("Input", streamDebugTest(mainClass, new CfDebugTestConfig(inputJar)))
        .add("R8/CF", streamDebugTest(mainClass, new CfDebugTestConfig(output1)))
        .add("R8/CF^2", streamDebugTest(mainClass, new CfDebugTestConfig(output2)))
        .compare();
  }

  private Stream<DebuggeeState> streamDebugTest(String mainClass, DebugTestConfig config)
      throws Exception {
    return streamDebugTest(config, mainClass, ANDROID_FILTER);
  }
}
