// Copyright (c) 2022, 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.utils;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
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 java.util.stream.Collectors;

public class DaggerUtils {

  private static final Path DAGGER_ROOT = Paths.get("third_party", "dagger", "2.41");
  private static final List<Path> DAGGER_COMPILER =
      ImmutableList.of(
              "annotations-13.0.jar",
              "checker-compat-qual-2.5.5.jar",
              "checker-qual-3.12.0.jar",
              "dagger-2.41.jar",
              "dagger-compiler-2.41.jar",
              "dagger-producers-2.41.jar",
              "dagger-spi-2.41.jar",
              "error_prone_annotations-2.7.1.jar",
              "failureaccess-1.0.1.jar",
              "google-java-format-1.5.jar",
              "guava-31.0.1-jre.jar",
              "incap-0.2.jar",
              "j2objc-annotations-1.3.jar",
              "javac-shaded-9-dev-r4023-3.jar",
              "javapoet-1.13.0.jar",
              "javax.inject-1.jar",
              "jsr305-3.0.2.jar",
              "kotlin-stdlib-1.5.32.jar",
              "kotlin-stdlib-common-1.5.32.jar",
              "kotlin-stdlib-jdk7-1.5.32.jar",
              "kotlin-stdlib-jdk8-1.5.32.jar",
              "kotlinx-metadata-jvm-0.3.0.jar",
              "symbol-processing-api-1.5.30-1.0.0.jar")
          .stream()
          .map(DAGGER_ROOT::resolve)
          .collect(ImmutableList.toImmutableList());
  private static final List<Path> DAGGER_RUNTIME =
      ImmutableList.of("dagger-2.41.jar", "javax.inject-1.jar").stream()
          .map(DAGGER_ROOT::resolve)
          .collect(ImmutableList.toImmutableList());

  public static List<Path> getDaggerRuntime() {
    return DAGGER_RUNTIME;
  }

  public static Path compileWithAnnotationProcessing(
      String target, Collection<Path> sourceFiles, Collection<Path> classFiles) throws Exception {
    // Class files are provided in JAR files. Extract all the class names to pass to javac for
    // annotation processing.
    List<String> classNames = new ArrayList<>();
    for (Path path : classFiles) {
      ZipUtils.iter(
          path,
          (entry, inputStream) -> {
            String entryString = entry.toString();
            if (FileUtils.isClassFile(entryString)) {
              byte[] bytes = ByteStreams.toByteArray(inputStream);
              classNames.add(TestBase.extractClassName(bytes));
            }
          });
    }
    return TestBase.javac(getJdk(), TestBase.getStaticTemp())
        .setSource(target)
        .setTarget(target)
        .addSourceFiles(sourceFiles)
        .addClassNames(classNames)
        .addClasspathFiles(classFiles)
        .addClasspathFiles(getDaggerRuntime())
        .addAnnotationProcessorPathFiles(DAGGER_COMPILER)
        .addAnnotationProcessors("dagger.internal.codegen.ComponentProcessor")
        .compile();
  }

  public static Path compileWithAnnotationProcessing(String target, Collection<Path> files)
      throws Exception {
    // Split the files passed into source files and class files. Class files are expected to be in
    // JARs.
    List<Path> sourceFiles =
        files.stream().filter(FileUtils::isJavaFile).collect(Collectors.toList());
    List<Path> classFiles =
        files.stream().filter(FileUtils::isJarFile).collect(Collectors.toList());
    assertEquals(files.size(), sourceFiles.size() + classFiles.size());
    return compileWithAnnotationProcessing(target, sourceFiles, classFiles);
  }

  public static Path compileWithoutAnnotationProcessing(String target, Collection<Path> files)
      throws Exception {
    return TestBase.javac(getJdk(), TestBase.getStaticTemp())
        .addSourceFiles(files)
        .addClasspathFiles(getDaggerRuntime())
        .compile();
  }

  public static Path compileWithoutAnnotationProcessing(String target, Path... files)
      throws Exception {
    return compileWithoutAnnotationProcessing(target, Arrays.asList(files));
  }

  public static Path compileWithAnnotationProcessing(String target, Path... files)
      throws Exception {
    return compileWithAnnotationProcessing(target, Arrays.asList(files));
  }

  private static CfRuntime getJdk() {
    return TestRuntime.getCheckedInJdk11();
  }
}
