// Copyright (c) 2017, 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.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.utils.BooleanUtils;
import java.nio.file.Paths;
import java.util.Collection;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class ExtractMarkerTest extends TestBase {
  private static final String CLASS_FILE =
      ToolHelper.EXAMPLES_BUILD_DIR + "classes/trivial/Trivial.class";

  private final TestParameters parameters;
  private boolean includeClassesChecksum;

  @Parameterized.Parameters(name = "{0}, includeClassesChecksum: {1}")
  public static Collection<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimes().withAllApiLevels().build(), BooleanUtils.values());
  }

  public ExtractMarkerTest(TestParameters parameters, boolean includeClassesChecksum) {
    this.parameters = parameters;
    this.includeClassesChecksum = includeClassesChecksum;
  }

  private void verifyMarkerDex(Marker marker, Tool tool) {
    assertEquals(tool, marker.getTool());
    assertEquals(Version.LABEL, marker.getVersion());
    assertEquals(CompilationMode.DEBUG.toString().toLowerCase(), marker.getCompilationMode());
    assertEquals(parameters.getApiLevel().getLevel(), marker.getMinApi().intValue());
    assertEquals(includeClassesChecksum, marker.getHasChecksums());
  }

  @Test
  public void extractMarkerTestDex() throws CompilationFailedException {
    Assume.assumeTrue(parameters.getRuntime().isDex());

    boolean[] testExecuted = {false};
    D8.run(
        D8Command.builder()
            .addProgramFiles(Paths.get(CLASS_FILE))
            .setMinApiLevel(parameters.getApiLevel().getLevel())
            .setIncludeClassesChecksum(includeClassesChecksum)
            .setProgramConsumer(
                new DexIndexedConsumer.ForwardingConsumer(null) {
                  @Override
                  public void acceptDexIndexedFile(DexIndexedConsumerData data) {
                    Marker marker;
                    try {
                      Collection<Marker> markers =
                          ExtractMarker.extractMarkerFromDexProgramData(data.getByteDataCopy());
                      assertEquals(1, markers.size());
                      marker = markers.iterator().next();
                    } catch (Exception e) {
                      throw new RuntimeException(e);
                    }
                    verifyMarkerDex(marker, Tool.D8);
                    testExecuted[0] = true;
                  }
                })
            .build());
    assertTrue(testExecuted[0]);
  }

  private static void verifyMarkerCf(Marker marker, Tool tool) {
    assertEquals(tool, marker.getTool());
    assertEquals(Version.LABEL, marker.getVersion());
    assertEquals(CompilationMode.DEBUG.toString().toLowerCase(), marker.getCompilationMode());
    assertFalse(marker.getHasChecksums());
  }

  @Test
  public void extractMarkerTestCf() throws CompilationFailedException {
    Assume.assumeTrue(parameters.getRuntime().isCf());
    Assume.assumeFalse(includeClassesChecksum);

    boolean[] testExecuted = {false};
    R8.run(
        R8Command.builder()
            .addProgramFiles(Paths.get(CLASS_FILE))
            .addLibraryFiles(ToolHelper.getJava8RuntimeJar())
            .setMode(CompilationMode.DEBUG)
            .setDisableTreeShaking(true)
            .setProgramConsumer(
                new ClassFileConsumer.ForwardingConsumer(null) {
                  @Override
                  public void acceptClassFile(ClassFileConsumerData data) {
                    Marker marker;
                    try {
                      Collection<Marker> markers =
                          ExtractMarker.extractMarkerFromClassProgramData(data.getByteDataCopy());
                      assertEquals(1, markers.size());
                      marker = markers.iterator().next();
                    } catch (Exception e) {
                      throw new RuntimeException(e);
                    }
                    verifyMarkerCf(marker, Tool.R8);
                    testExecuted[0] = true;
                  }
                })
            .build());
    assertTrue(testExecuted[0]);
  }

  @Test
  public void backendValueCompatibilityTestForMinApi() {
    DexItemFactory factory = new DexItemFactory();
    DexString markerString =
        factory.createString(
            "~~D8{\"compilation-mode\":\"debug\",\"has-checksums\":false,"
                + "\"min-api\":21,\"sha-1\":\"engineering\",\"version\":\"main\" }");
    assertEquals("dex", Marker.parse(markerString).getBackend());
  }

  @Test
  public void backendValueCompatibilityTestForR8Cf() {
    DexItemFactory factory = new DexItemFactory();
    DexString markerString =
        factory.createString(
            "~~R8{\"compilation-mode\":\"release\",\"has-checksums\":true,"
                + "\"sha-1\":\"engineering\",\"version\":\"main\" }");
    assertEquals("cf", Marker.parse(markerString).getBackend());
  }
}
