// Copyright (c) 2019, 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;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.android.tools.r8.utils.InternalOptions;
import java.io.IOException;
import java.nio.file.Path;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

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

  static final int UNSUPPORTED_CF_VERSION = InternalOptions.SUPPORTED_CF_VERSION.major() + 1;
  static final int UNSUPPORTED_DEX_VERSION = InternalOptions.SUPPORTED_DEX_VERSION + 1;

  private final TestParameters parameters;

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

  public FailCompilationOnFutureVersionsTest(TestParameters parameters) {
    this.parameters = parameters;
    assertTrue("Test assumes the first DEX version char is '0'.", UNSUPPORTED_DEX_VERSION < 100);
  }

  @Test
  public void testDex() throws CompilationFailedException, IOException {
    // Generate a DEX file with a version higher than the supported one.
    Path out =
        testForD8()
            .addProgramClasses(TestClass.class)
            .setMinApi(parameters.getApiLevel())
            .addOptionsModification(
                options ->
                    options.testing.forceDexVersionBytes =
                        ("0" + UNSUPPORTED_DEX_VERSION).getBytes())
            .compile()
            .writeToZip();
    try {
      testForD8()
          .addProgramFiles(out)
          .setMinApi(parameters.getApiLevel())
          .compileWithExpectedDiagnostics(
              diagnotics -> {
                diagnotics.assertOnlyErrors();
                diagnotics.assertErrorsCount(1);
                assertThat(
                    diagnotics.getErrors().get(0).getDiagnosticMessage(),
                    containsString("Unsupported DEX file version: 0" + UNSUPPORTED_DEX_VERSION));
              });
    } catch (CompilationFailedException e) {
      return;
    }
    fail("Expected compilation error");
  }

  @Test
  public void testCf() {
    try {
      testForD8()
          .addProgramClassFileData(CfDump.dump())
          .setMinApi(parameters.getApiLevel())
          .compileWithExpectedDiagnostics(
              diagnotics -> {
                diagnotics.assertOnlyErrors();
                diagnotics.assertErrorsCount(1);
                assertThat(
                    diagnotics.getErrors().get(0).getDiagnosticMessage(),
                    containsString("Unsupported class file version: " + UNSUPPORTED_CF_VERSION));
                assertTrue(
                    diagnotics.getErrors().stream()
                        .allMatch(
                            s ->
                                s.getDiagnosticMessage()
                                    .toLowerCase()
                                    .contains("unsupported class file version")));
              });
    } catch (CompilationFailedException e) {
      return;
    }
    fail("Expected compilation error");
  }

  public static class CfDump implements Opcodes {

    public static byte[] dump() {
      // Generate a class file with a version higher than the supported one.
      ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
      MethodVisitor mv;
      cw.visit(
          UNSUPPORTED_CF_VERSION, ACC_PUBLIC + ACC_SUPER, "Test", null, "java/lang/Object", null);
      {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
      }
      cw.visitEnd();
      return cw.toByteArray();
    }
  }

  public static class TestClass {
    // Intentionally empty stub class for the DEX generation.
  }
}
