// Copyright (C) 2009 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.pgm.init;

import com.google.common.base.Strings;
import com.google.common.hash.Funnels;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import com.google.gerrit.common.Die;
import com.google.gerrit.common.IoUtil;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;

import org.eclipse.jgit.util.HttpSupport;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/** Get optional or required 3rd party library files into $site_path/lib. */
class LibraryDownloader {
  private final ConsoleUI ui;
  private final Path lib_dir;

  private boolean required;
  private String name;
  private String jarUrl;
  private String sha1;
  private String remove;
  private List<LibraryDownloader> needs;
  private LibraryDownloader neededBy;
  private Path dst;
  private boolean download; // download or copy
  private boolean exists;

  @Inject
  LibraryDownloader(ConsoleUI ui, SitePaths site) {
    this.ui = ui;
    this.lib_dir = site.lib_dir;
    this.needs = new ArrayList<>(2);
  }

  void setName(final String name) {
    this.name = name;
  }

  void setJarUrl(final String url) {
    this.jarUrl = url;
    download = jarUrl.startsWith("http");
  }

  void setSHA1(final String sha1) {
    this.sha1 = sha1;
  }

  void setRemove(String remove) {
    this.remove = remove;
  }

  void addNeeds(LibraryDownloader lib) {
    needs.add(lib);
  }

  void downloadRequired() {
    setRequired(true);
    download();
  }

  void downloadOptional() {
    required = false;
    download();
  }

  private void setRequired(boolean r) {
    required = r;
    for (LibraryDownloader d : needs) {
      d.setRequired(r);
    }
  }

  private void download() {
    if (jarUrl == null || !jarUrl.contains("/")) {
      throw new IllegalStateException("Invalid JarUrl for " + name);
    }

    final String jarName = jarUrl.substring(jarUrl.lastIndexOf('/') + 1);
    if (jarName.contains("/") || jarName.contains("\\")) {
      throw new IllegalStateException("Invalid JarUrl: " + jarUrl);
    }

    if (name == null) {
      name = jarName;
    }

    dst = lib_dir.resolve(jarName);
    if (Files.exists(dst)) {
      exists = true;
    } else if (shouldGet()) {
      doGet();
    }

    if (exists) {
      for (LibraryDownloader d : needs) {
        d.neededBy = this;
        d.downloadRequired();
      }
    }
  }

  private boolean shouldGet() {
    if (ui.isBatch()) {
      return required;

    } else {
      final StringBuilder msg = new StringBuilder();
      msg.append("\n");
      msg.append("Gerrit Code Review is not shipped with %s\n");
      if (neededBy != null) {
        msg.append(String.format(
            "** This library is required by %s. **\n",
            neededBy.name));
      } else if (required) {
        msg.append("**  This library is required for your configuration. **\n");
      } else {
        msg.append("  If available, Gerrit can take advantage of features\n");
        msg.append("  in the library, but will also function without it.\n");
      }
      msg.append(String.format(
          "%s and install it now", download ? "Download" : "Copy"));
      return ui.yesno(true, msg.toString(), name);
    }
  }

  private void doGet() {
    if (!Files.exists(lib_dir)) {
      try {
        Files.createDirectories(lib_dir);
      } catch (IOException e) {
        throw new Die("Cannot create " + lib_dir, e);
      }
    }

    try {
      removeStaleVersions();
      if (download) {
        doGetByHttp();
      } else {
        doGetByLocalCopy();
      }
      verifyFileChecksum();
    } catch (IOException err) {
      try {
        Files.delete(dst);
      } catch (IOException e) {
        // Delete failed; leave alone.
      }

      if (ui.isBatch()) {
        throw new Die("error: Cannot get " + jarUrl, err);
      }

      System.err.println();
      System.err.println();
      System.err.println("error: " + err.getMessage());
      System.err.println("Please download:");
      System.err.println();
      System.err.println("  " + jarUrl);
      System.err.println();
      System.err.println("and save as:");
      System.err.println();
      System.err.println("  " + dst.toAbsolutePath());
      System.err.println();
      System.err.flush();

      ui.waitForUser();

      if (Files.exists(dst)) {
        verifyFileChecksum();

      } else if (!ui.yesno(!required, "Continue without this library")) {
        throw new Die("aborted by user");
      }
    }

    if (Files.exists(dst)) {
      exists = true;
      IoUtil.loadJARs(dst);
    }
  }

  private void removeStaleVersions() {
    if (!Strings.isNullOrEmpty(remove)) {
      DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
        @Override
        public boolean accept(Path entry) {
          return entry.getFileName().toString()
              .matches("^" + remove + "$");
        }
      };
      try (DirectoryStream<Path> paths =
          Files.newDirectoryStream(lib_dir, filter)) {
        for (Path p : paths) {
          String old = p.getFileName().toString();
          String bak = "." + old + ".backup";
          ui.message("Renaming %s to %s\n", old, bak);
          try {
            Files.move(p, p.resolveSibling(bak));
          } catch (IOException e) {
            throw new Die("cannot rename " + old, e);
          }
        }
      } catch (IOException e) {
        throw new Die("cannot remove stale library versions", e);
      }
    }
  }

  private void doGetByLocalCopy() throws IOException {
    System.err.print("Copying " + jarUrl + " ...");
    Path p = url2file(jarUrl);
    if (!Files.exists(p)) {
      StringBuilder msg = new StringBuilder()
          .append("\n")
          .append("Can not find the %s at this location: %s\n")
          .append("Please provide alternative URL");
      p = url2file(ui.readString(null, msg.toString(), name, jarUrl));
    }
    Files.copy(p, dst);
  }

  private static Path url2file(final String urlString) throws IOException {
    final URL url = new URL(urlString);
    try {
      return Paths.get(url.toURI());
    } catch (URISyntaxException e) {
      return Paths.get(url.getPath());
    }
  }

  private void doGetByHttp() throws IOException {
    System.err.print("Downloading " + jarUrl + " ...");
    System.err.flush();
    try (InputStream in = openHttpStream(jarUrl);
        OutputStream out = Files.newOutputStream(dst)) {
      ByteStreams.copy(in, out);
      System.err.println(" OK");
      System.err.flush();
    } catch (IOException err) {
      deleteDst();
      System.err.println(" !! FAIL !!");
      System.err.flush();
      throw err;
    }
  }

  private static InputStream openHttpStream(String urlStr) throws IOException {
    ProxySelector proxySelector = ProxySelector.getDefault();
    URL url = new URL(urlStr);
    Proxy proxy = HttpSupport.proxyFor(proxySelector, url);
    HttpURLConnection c = (HttpURLConnection) url.openConnection(proxy);

    switch (HttpSupport.response(c)) {
      case HttpURLConnection.HTTP_OK:
        return c.getInputStream();

      case HttpURLConnection.HTTP_NOT_FOUND:
        throw new FileNotFoundException(url.toString());

      default:
        throw new IOException(url.toString() + ": " + HttpSupport.response(c)
            + " " + c.getResponseMessage());
    }
  }

  private void verifyFileChecksum() {
    if (sha1 == null) {
      System.err.println();
      System.err.flush();
      return;
    }
    Hasher h = Hashing.sha1().newHasher();
    try (InputStream in = Files.newInputStream(dst);
        OutputStream out = Funnels.asOutputStream(h)) {
      ByteStreams.copy(in, out);
    } catch (IOException e) {
      deleteDst();
      throw new Die("cannot checksum " + dst, e);
    }
    if (sha1.equals(h.hash().toString())) {
      System.err.println("Checksum " + dst.getFileName() + " OK");
      System.err.flush();
    } else if (ui.isBatch()) {
      deleteDst();
      throw new Die(dst + " SHA-1 checksum does not match");

    } else if (!ui.yesno(null /* force an answer */,
        "error: SHA-1 checksum does not match\n" + "Use %s anyway",//
        dst.getFileName())) {
      deleteDst();
      throw new Die("aborted by user");
    }
  }

  private void deleteDst() {
    try {
      Files.delete(dst);
    } catch (IOException e) {
      System.err.println(" Failed to clean up lib: " + dst);
    }
  }
}
