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

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.R8;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvokeDynamic;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class LambdaTestRunner {

  private static final Class<?> CLASS = LambdaTest.class;
  private static final String METHOD = "main";

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

  @Test
  public void test() throws Exception {
    // Test that the InvokeDynamic instruction in LambdaTest.main()
    // is not modified by the R8 compilation.
    // First, extract the InvokeDynamic instruction from the input class.
    byte[] inputClass = ToolHelper.getClassAsBytes(CLASS);
    AndroidApp inputApp =
        AndroidApp.builder().addClassProgramData(inputClass, Origin.unknown()).build();
    CfInvokeDynamic insnInput = findFirstInMethod(inputApp);
    Assert.assertNotNull("No CfInvokeDynamic found in input", insnInput);
    // Compile with R8 and extract the InvokeDynamic instruction from the output class.
    AndroidAppConsumers appBuilder = new AndroidAppConsumers();
    Path outPath = temp.getRoot().toPath().resolve("out.jar");
    R8.run(
        R8Command.builder()
            .setMode(CompilationMode.DEBUG)
            .setDisableTreeShaking(true)
            .setDisableMinification(true)
            .addLibraryFiles(ToolHelper.getJava8RuntimeJar())
            .setProgramConsumer(appBuilder.wrapClassFileConsumer(new ArchiveConsumer(outPath)))
            .addClassProgramData(inputClass, Origin.unknown())
            .build());
    AndroidApp outputApp = appBuilder.build();
    CfInvokeDynamic insnOutput = findFirstInMethod(outputApp);
    Assert.assertNotNull("No CfInvokeDynamic found in output", insnOutput);
    // Check that the InvokeDynamic instruction is not modified.
    assertEquals(print(insnInput), print(insnOutput));
    // Check that execution gives the same output.
    ProcessResult inputResult =
        ToolHelper.runJava(ToolHelper.getClassPathForTests(), CLASS.getName());
    ProcessResult outputResult = ToolHelper.runJava(outPath, CLASS.getName());
    assertEquals(inputResult.toString(), outputResult.toString());
  }

  private static CfInvokeDynamic findFirstInMethod(AndroidApp app) throws Exception {
    String returnType = "void";
    CodeInspector inspector = new CodeInspector(app);
    List<String> args = Collections.singletonList(String[].class.getTypeName());
    DexEncodedMethod method = inspector.clazz(CLASS).method(returnType, METHOD, args).getMethod();
    CfCode code = method.getCode().asCfCode();
    for (CfInstruction instruction : code.getInstructions()) {
      if (instruction instanceof CfInvokeDynamic) {
        return (CfInvokeDynamic) instruction;
      }
    }
    return null;
  }

  private static String print(CfInstruction instruction) {
    CfPrinter printer = new CfPrinter();
    instruction.print(printer);
    return printer.toString();
  }

}
