// 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.D8Command.Builder;
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.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, D8Command.Builder builder) {
      addClasspathPath(getClassesRoot(testJarFile), builder);
      addClasspathPath(getLegacyClassesRoot(testJarFile, packageName), builder);
    }

    private void addClasspathPath(Path location, D8Command.Builder builder) {
      builder.addClasspathResourceProvider(
          DirectoryClassFileProvider.fromDirectory(location.resolve("..")));
    }

    @Override
    void addLibraryReference(Builder builder, Path location) throws IOException {
      builder.addLibraryResourceProvider(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;
  }

}
