// 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;
import com.android.tools.r8.DexIndexedConsumer;
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.origin.Origin;
import com.android.tools.r8.utils.DescriptorUtils;
import java.nio.file.Path;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class AlwaysNullGetItemTestRunner {
  static final Class CLASS = AlwaysNullGetItemTest.class;

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

  @Test
  public void test() throws Exception {
    ProcessResult runInput =
        ToolHelper.runJava(ToolHelper.getClassPathForTests(), CLASS.getCanonicalName());
    assertEquals(0, runInput.exitCode);
    Path outCf = temp.getRoot().toPath().resolve("cf.jar");
    Path outDex = temp.getRoot().toPath().resolve("dex.zip");
    R8.run(
        R8Command.builder()
            .setMode(CompilationMode.DEBUG)
            .addClassProgramData(ToolHelper.getClassAsBytes(CLASS), Origin.unknown())
            .addLibraryFiles(ToolHelper.getAndroidJar(ToolHelper.getMinApiLevelForDexVm()))
            .setProgramConsumer(new DexIndexedConsumer.ArchiveConsumer(outDex))
            .build());
    R8.run(
        R8Command.builder()
            .setMode(CompilationMode.DEBUG)
            .addClassProgramData(ToolHelper.getClassAsBytes(CLASS), Origin.unknown())
            .addLibraryFiles(ToolHelper.getAndroidJar(ToolHelper.getMinApiLevelForDexVm()))
            .setProgramConsumer(new ClassFileConsumer.ArchiveConsumer(outCf))
            .build());
    ProcessResult runCf = ToolHelper.runJava(outCf, CLASS.getCanonicalName());
    ProcessResult runDex = ToolHelper.runArtRaw(outDex.toString(), CLASS.getCanonicalName());
    assertEquals(runInput.toString(), runCf.toString());
    // Only compare stdout and exitCode since dex2oat prints to stderr.
    assertEquals(runInput.stdout, runDex.stdout);
    assertEquals(runInput.exitCode, runDex.exitCode);
  }

  @Test
  public void testNoCheckCast() throws Exception {
    // Test that JVM accepts javac output when method calls have been replaced by ACONST_NULL.
    Path out = temp.getRoot().toPath().resolve("aaload-null.jar");
    ClassFileConsumer.ArchiveConsumer archiveConsumer = new ClassFileConsumer.ArchiveConsumer(out);
    archiveConsumer.accept(
        AlwaysNullGetItemDump.dump(),
        DescriptorUtils.javaTypeToDescriptor(CLASS.getCanonicalName()),
        null);
    archiveConsumer.finished(null);
    ProcessResult processResult = ToolHelper.runJava(out, CLASS.getCanonicalName());
    if (processResult.exitCode != 0) {
      System.out.println(processResult);
    }
    assertEquals(0, processResult.exitCode);
  }
}
