// 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.io.Files;
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.lib.ObjectId;
import org.eclipse.jgit.util.HttpSupport;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
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.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
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 File 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 File 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 = new File(lib_dir, jarName);
    if (dst.exists()) {
      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 (!lib_dir.exists() && !lib_dir.mkdirs()) {
      throw new Die("Cannot create " + lib_dir);
    }

    try {
      removeStaleVersions();
      if (download) {
        doGetByHttp();
      } else {
        doGetByLocalCopy();
      }
      verifyFileChecksum();
    } catch (IOException err) {
      dst.delete();

      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.getAbsolutePath());
      System.err.println();
      System.err.flush();

      ui.waitForUser();

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

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

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

  private void removeStaleVersions() {
    if (!Strings.isNullOrEmpty(remove)) {
      String[] names = lib_dir.list(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
          return name.matches("^" + remove + "$");
        }
      });
      if (names != null) {
        for (String old : names) {
          String bak = "." + old + ".backup";
          ui.message("Renaming %s to %s", old, bak);
          if (!new File(lib_dir, old).renameTo(new File(lib_dir, bak))) {
            throw new Die("cannot rename " + old);
          }
        }
      }
    }
  }

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

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

  private void doGetByHttp() throws IOException {
    System.err.print("Downloading " + jarUrl + " ...");
    System.err.flush();
    try {
      final ProxySelector proxySelector = ProxySelector.getDefault();
      final URL url = new URL(jarUrl);
      final Proxy proxy = HttpSupport.proxyFor(proxySelector, url);
      final HttpURLConnection c = (HttpURLConnection) url.openConnection(proxy);
      final InputStream in;

      switch (HttpSupport.response(c)) {
        case HttpURLConnection.HTTP_OK:
          in = c.getInputStream();
          break;

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

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

      try {
        final OutputStream out = new FileOutputStream(dst);
        try {
          final byte[] buf = new byte[8192];
          int n;
          while ((n = in.read(buf)) > 0) {
            out.write(buf, 0, n);
          }
        } finally {
          out.close();
        }
      } finally {
        in.close();
      }
      System.err.println(" OK");
      System.err.flush();
    } catch (IOException err) {
      dst.delete();
      System.err.println(" !! FAIL !!");
      System.err.flush();
      throw err;
    }
  }

  private void verifyFileChecksum() {
    if (sha1 != null) {
      try {
        final MessageDigest md = MessageDigest.getInstance("SHA-1");
        final FileInputStream in = new FileInputStream(dst);
        try {
          final byte[] buf = new byte[8192];
          int n;
          while ((n = in.read(buf)) > 0) {
            md.update(buf, 0, n);
          }
        } finally {
          in.close();
        }

        if (sha1.equals(ObjectId.fromRaw(md.digest()).name())) {
          System.err.println("Checksum " + dst.getName() + " OK");
          System.err.flush();

        } else if (ui.isBatch()) {
          dst.delete();
          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.getName())) {
          dst.delete();
          throw new Die("aborted by user");
        }

      } catch (IOException checksumError) {
        dst.delete();
        throw new Die("cannot checksum " + dst, checksumError);

      } catch (NoSuchAlgorithmException checksumError) {
        dst.delete();
        throw new Die("cannot checksum " + dst, checksumError);
      }
    }
  }
}
