// Copyright (c) 2021, 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.retrace.api;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.Collectors;
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.transformers.ClassFileTransformer;
import com.android.tools.r8.transformers.ClassFileTransformer.InnerClassPredicate;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.ZipUtils;
import com.android.tools.r8.utils.ZipUtils.ZipBuilder;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.rules.TemporaryFolder;

public class RetraceApiTestHelper {

  private static final String JUNIT_JAR = "junit-4.13-beta-2.jar";
  private static final String HAMCREST = "hamcrest-core-1.3.jar";

  public static List<Class<? extends RetraceApiBinaryTest>> CLASSES_FOR_BINARY_COMPATIBILITY =
      ImmutableList.of(
          RetraceApiEmptyTest.RetraceTest.class,
          RetraceApiSourceFileTest.ApiTest.class,
          RetraceApiSourceFileNotFoundTest.ApiTest.class,
          RetraceApiInferSourceFileTest.ApiTest.class,
          RetraceApiSynthesizedClassTest.ApiTest.class,
          RetraceApiSynthesizedFieldTest.ApiTest.class,
          RetraceApiSynthesizedMethodTest.ApiTest.class,
          RetraceApiSynthesizedFrameTest.ApiTest.class,
          RetraceApiSynthesizedInnerFrameTest.ApiTest.class,
          RetraceApiUnknownJsonTest.ApiTest.class);
  public static List<Class<? extends RetraceApiBinaryTest>> CLASSES_PENDING_BINARY_COMPATIBILITY =
      ImmutableList.of();

  public static void runJunitOnTests(
      CfRuntime runtime,
      Path r8Jar,
      Class<? extends RetraceApiBinaryTest> clazz,
      TemporaryFolder temp)
      throws Exception {
    assertTrue(testIsSpecifiedAsBinaryOrPending(clazz));
    List<Class<? extends RetraceApiBinaryTest>> testClasses = ImmutableList.of(clazz);
    runJunitOnTests(
        runtime, r8Jar, generateJarForRetraceBinaryTests(temp, testClasses), testClasses);
  }

  public static void runJunitOnTests(
      CfRuntime runtime,
      Path r8Jar,
      Path testJar,
      Collection<Class<? extends RetraceApiBinaryTest>> tests)
      throws Exception {
    List<Path> classPaths = ImmutableList.of(getJunitDependency(), getHamcrest(), r8Jar, testJar);
    List<String> args = new ArrayList<>();
    args.add("org.junit.runner.JUnitCore");
    tests.forEach(test -> args.add(test.getTypeName()));
    ProcessResult processResult =
        ToolHelper.runJava(runtime, classPaths, args.toArray(new String[0]));
    assertEquals(processResult.toString(), 0, processResult.exitCode);
    assertThat(processResult.stdout, containsString("OK (" + tests.size() + " test"));
  }

  private static Path getJunitDependency() {
    String junitPath =
        Arrays.stream(System.getProperty("java.class.path").split(File.pathSeparator))
            .filter(cp -> cp.endsWith(JUNIT_JAR))
            .collect(Collectors.toSingle());
    return Paths.get(junitPath);
  }

  private static Path getHamcrest() {
    String junitPath =
        Arrays.stream(System.getProperty("java.class.path").split(File.pathSeparator))
            .filter(cp -> cp.endsWith(HAMCREST))
            .collect(Collectors.toSingle());
    return Paths.get(junitPath);
  }

  public static Path generateJarForRetraceBinaryTests(
      TemporaryFolder temp, Collection<Class<? extends RetraceApiBinaryTest>> classes)
      throws Exception {
    Path jar = File.createTempFile("retrace_api_tests", ".jar", temp.getRoot()).toPath();
    ZipBuilder zipBuilder = ZipBuilder.builder(jar);
    for (Class<? extends RetraceApiBinaryTest> retraceApiTest : classes) {
      zipBuilder.addFilesRelative(
          ToolHelper.getClassPathForTests(),
          ToolHelper.getClassFilesForInnerClasses(retraceApiTest));
      zipBuilder.addBytes(
          ZipUtils.zipEntryNameForClass(retraceApiTest),
          ClassFileTransformer.create(retraceApiTest)
              .removeInnerClasses(
                  InnerClassPredicate.onName(
                      DescriptorUtils.getBinaryNameFromJavaType(retraceApiTest.getTypeName())))
              .transform());
    }
    zipBuilder.addFilesRelative(
        ToolHelper.getClassPathForTests(),
        ToolHelper.getClassFileForTestClass(RetraceApiBinaryTest.class));
    return zipBuilder.build();
  }

  public static Collection<Class<? extends RetraceApiBinaryTest>> getBinaryCompatibilityTests() {
    return CLASSES_FOR_BINARY_COMPATIBILITY;
  }

  private static boolean testIsSpecifiedAsBinaryOrPending(Class<?> clazz) {
    return CLASSES_FOR_BINARY_COMPATIBILITY.contains(clazz)
        || CLASSES_PENDING_BINARY_COMPATIBILITY.contains(clazz);
  }
}
