// Copyright (c) 2019, 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 tasks;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.os.OperatingSystem;

public class DownloadDependency extends DefaultTask {

  public enum Type {
    GOOGLE_STORAGE,
    X20
  }

  private Type type;
  private String dependency;
  private File outputDir;
  private File tarGzFile;
  private File sha1File;

  public void setType(Type type) {
    this.type = type;
  }

  public void setDependency(String dependency) {
    this.dependency = dependency;
    outputDir = new File(dependency);
    tarGzFile = new File(dependency + ".tar.gz");
    sha1File = new File(dependency + ".tar.gz.sha1");
  }

  @InputFiles
  public Collection<File> getInputFiles() {
    return Arrays.asList(sha1File, tarGzFile);
  }

  @OutputDirectory
  public File getOutputDir() {
    return outputDir;
  }

  public File getSha1File() {
    return sha1File;
  }

  public File getTarGzFile() {
    return tarGzFile;
  }

  @TaskAction
  public void execute() throws IOException, InterruptedException {
    // First run will write the tar.gz file, causing the second run to still be out-of-date.
    // Check if the modification time of the tar is newer than the sha in which case we are done.
    // Also, check the contents of the out directory because gradle appears to create it for us...
    if (outputDir.exists()
        && outputDir.isDirectory()
        && outputDir.list().length > 0
        && tarGzFile.exists()
        && sha1File.lastModified() <= tarGzFile.lastModified()) {
      return;
    }
    if (outputDir.exists() && outputDir.isDirectory()) {
      outputDir.delete();
    }
    if (type == Type.GOOGLE_STORAGE) {
      downloadFromGoogleStorage();
    } else if (type == Type.X20) {
      downloadFromX20();
    } else {
      throw new RuntimeException("Unexpected or missing dependency type: " + type);
    }
  }

  private void downloadFromGoogleStorage() throws IOException, InterruptedException {
    List<String> args = Arrays.asList("-n", "-b", "r8-deps", "-s", "-u", sha1File.toString());
    if (OperatingSystem.current().isWindows()) {
      List<String> command = new ArrayList<>();
      command.add("download_from_google_storage.bat");
      command.addAll(args);
      runProcess(new ProcessBuilder().command(command));
    } else {
      runProcess(
          new ProcessBuilder()
              .command("bash", "-c", "download_from_google_storage " + String.join(" ", args)));
    }
  }

  private void downloadFromX20() throws IOException, InterruptedException {
    if (OperatingSystem.current().isWindows()) {
      throw new RuntimeException("Downloading from x20 unsupported on windows");
    }
    runProcess(
        new ProcessBuilder()
            .command("bash", "-c", "tools/download_from_x20.py " + sha1File.toString()));
  }

  private static void runProcess(ProcessBuilder builder) throws IOException, InterruptedException {
    String command = String.join(" ", builder.command());
    Process p = builder.start();
    int exit = p.waitFor();
    if (exit != 0) {
      throw new IOException(
          "Process failed for "
              + command
              + "\n"
              + new BufferedReader(
                      new InputStreamReader(p.getErrorStream(), StandardCharsets.UTF_8))
                  .lines()
                  .collect(Collectors.joining("\n")));
    }
  }
}
