// 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 com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.OffOrAuto;
import com.android.tools.r8.utils.ZipUtils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.junit.Test;

public class D8LazyRunExamplesAndroidOTest
    extends D8IncrementalRunExamplesAndroidOTest {

  // Please note that all tool specific markers have been eliminated in the resulting
  // dex applications. This allows for byte-wise comparison of the results.

  class D8LazyTestRunner extends D8IncrementalTestRunner {

    D8LazyTestRunner(String testName, String packageName, String mainClass) {
      super(testName, packageName, mainClass);
    }

    @Override
    void addClasspathReference(
        Path testJarFile,
        Consumer<Path> pathConsumer,
        Consumer<ClassFileResourceProvider> providerConsumer) {
      addClasspathPath(getClassesRoot(testJarFile), providerConsumer);
      addClasspathPath(getLegacyClassesRoot(testJarFile, packageName), providerConsumer);
    }

    private void addClasspathPath(Path location, Consumer<ClassFileResourceProvider> fn) {
      fn.accept(DirectoryClassFileProvider.fromDirectory(location.resolve("..")));
    }

    @Override
    void addLibraryReference(
        Path location,
        Consumer<Path> pathConsumer,
        Consumer<ClassFileResourceProvider> providerConsumer)
        throws IOException {
      providerConsumer.accept(new ArchiveClassFileProvider(location));
    }

    @Override
    D8LazyTestRunner self() {
      return this;
    }
  }

  @Override
  D8IncrementalTestRunner test(String testName, String packageName, String mainClass) {
    D8IncrementalTestRunner result = new D8LazyTestRunner(testName, packageName, mainClass);
    result.withOptionConsumer(options -> options.setMarker(null));
    return result;
  }

  @Test
  public void dexPerClassFileWithDesugaringAndFolderClasspath() throws Throwable {
    AndroidApiLevel minAPILevel = AndroidApiLevel.K;
    Path inputFile =
        Paths.get(ToolHelper.EXAMPLES_ANDROID_N_BUILD_DIR, "interfacemethods" + JAR_EXTENSION);
    Path tmpClassesDir = temp.newFolder().toPath();
    ZipUtils.unzip(inputFile.toString(), tmpClassesDir.toFile());
    Path androidJar = ToolHelper.getAndroidJar(minAPILevel);

    // Build all at once.
    AndroidApp fullBuildResult;
    {
      D8Command.Builder command =
          D8Command.builder()
              .setMinApiLevel(minAPILevel.getLevel())
              .addLibraryFiles(androidJar)
              .addProgramFiles(inputFile);

      fullBuildResult = ToolHelper.runD8(
          command, options -> {
            options.interfaceMethodDesugaring = OffOrAuto.Auto;
            options.setMarker(null);
          });
    }

    // Build each class individually using tmpClassesDir as classpath for desugaring.
    List<ProgramResource> individalDexes = new ArrayList<>();
    List<Path> individualClassFiles =
        Files.walk(tmpClassesDir).filter(FileUtils::isClassFile).collect(Collectors.toList());
    for (Path classFile : individualClassFiles) {
      D8Command.Builder builder =
          D8Command.builder()
              .setMinApiLevel(minAPILevel.getLevel())
              .addLibraryFiles(androidJar)
              .addClasspathFiles(tmpClassesDir)
              .addProgramFiles(classFile);
      AndroidApp individualResult =
          ToolHelper.runD8(
              builder,
              options -> {
                options.interfaceMethodDesugaring = OffOrAuto.Auto;
                options.setMarker(null);
              });
      individalDexes.add(individualResult.getDexProgramResourcesForTesting().get(0));
    }
    AndroidApp mergedResult = mergeDexResources(minAPILevel.getLevel(), individalDexes);

    assertTrue(Arrays.equals(
        readResource(fullBuildResult.getDexProgramResourcesForTesting().get(0)),
        readResource(mergedResult.getDexProgramResourcesForTesting().get(0))));
  }

  private AndroidApp mergeDexResources(int minAPILevel, List<ProgramResource> individalDexes)
      throws IOException, CompilationFailedException, ResourceException {
    D8Command.Builder builder = D8Command.builder()
        .setMinApiLevel(minAPILevel);
    for (ProgramResource resource : individalDexes) {
      builder.addDexProgramData(readResource(resource), resource.getOrigin());
    }
    AndroidApp mergedResult = ToolHelper.runD8(builder, options -> options.setMarker(null));
    return mergedResult;
  }
}
