// 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;

import static java.util.stream.Collectors.joining;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.common.IoUtil;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.PluginData;
import com.google.gerrit.index.SchemaDefinitions;
import com.google.gerrit.index.project.ProjectSchemaDefinitions;
import com.google.gerrit.pgm.init.BaseInit;
import com.google.gerrit.pgm.init.Browser;
import com.google.gerrit.pgm.init.InitPlugins;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.util.ErrorLogFile;
import com.google.gerrit.server.config.GerritServerConfigModule;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.index.GerritIndexStatus;
import com.google.gerrit.server.index.account.AccountSchemaDefinitions;
import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
import com.google.gerrit.server.index.group.GroupSchemaDefinitions;
import com.google.gerrit.server.ioutil.HostPlatform;
import com.google.gerrit.server.securestore.SecureStoreClassName;
import com.google.gerrit.server.util.ReplicaUtil;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.util.Providers;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.kohsuke.args4j.Option;

/** Initialize a new Gerrit installation. */
public class Init extends BaseInit {
  @Option(
      name = "--batch",
      aliases = {"-b"},
      usage = "Batch mode; skip interactive prompting")
  private boolean batchMode;

  @Option(name = "--delete-caches", usage = "Delete all persistent caches without asking")
  private boolean deleteCaches;

  @Option(name = "--no-auto-start", usage = "Don't automatically start daemon after init")
  private boolean noAutoStart;

  @Option(name = "--skip-plugins", usage = "Don't install plugins")
  private boolean skipPlugins;

  @Option(name = "--list-plugins", usage = "List available plugins")
  private boolean listPlugins;

  @Option(name = "--install-plugin", usage = "Install given plugin without asking")
  private List<String> installPlugins;

  @Option(name = "--install-all-plugins", usage = "Install all plugins from war without asking")
  private boolean installAllPlugins;

  @Option(
      name = "--secure-store-lib",
      usage = "Path to jar providing SecureStore implementation class")
  private String secureStoreLib;

  @Option(name = "--dev", usage = "Setup site with default options suitable for developers")
  private boolean dev;

  @Option(name = "--skip-all-downloads", usage = "Don't download libraries")
  private boolean skipAllDownloads;

  @Option(name = "--skip-download", usage = "Don't download given library")
  private List<String> skippedDownloads;

  @Option(name = "--reindex-threads", usage = "Number of threads to use for reindex after init")
  private int reindexThreads = 1;

  @Option(name = "--show-cache-stats", usage = "Show cache statistics at the end")
  private boolean showCacheStats;

  @Inject Browser browser;

  private GerritIndexStatus indexStatus;

  public Init() {
    super(new WarDistribution(), null);
  }

  public Init(Path sitePath) {
    super(sitePath, true, new WarDistribution(), null);
    batchMode = true;
    noAutoStart = true;
  }

  @Override
  protected boolean beforeInit(SiteInit init) throws Exception {
    indexStatus = new GerritIndexStatus(init.site);
    ErrorLogFile.errorOnlyConsole();

    if (!skipPlugins) {
      final List<PluginData> plugins =
          InitPlugins.listPluginsAndRemoveTempFiles(init.site, pluginsDistribution);
      ConsoleUI ui = ConsoleUI.getInstance(false);
      if (installAllPlugins && !nullOrEmpty(installPlugins)) {
        ui.message("Cannot use --install-plugin together with --install-all-plugins.\n");
        return true;
      }
      verifyInstallPluginList(ui, plugins);
      if (listPlugins) {
        if (!plugins.isEmpty()) {
          ui.message("Available plugins:\n");
          for (PluginData plugin : plugins) {
            ui.message(" * %s version %s\n", plugin.name, plugin.version);
          }
        } else {
          ui.message("No plugins found.\n");
        }
        return true;
      }
    }
    return false;
  }

  @Override
  protected void afterInit(SiteRun run) throws Exception {
    List<SchemaDefinitions<?>> schemaDefs =
        ImmutableList.of(
            AccountSchemaDefinitions.INSTANCE,
            ChangeSchemaDefinitions.INSTANCE,
            GroupSchemaDefinitions.INSTANCE,
            ProjectSchemaDefinitions.INSTANCE);
    List<Module> modules = new ArrayList<>();
    modules.add(
        new AbstractModule() {
          @Override
          protected void configure() {
            bind(Path.class).annotatedWith(SitePath.class).toInstance(getSitePath());
            bind(Browser.class);
            bind(String.class)
                .annotatedWith(SecureStoreClassName.class)
                .toProvider(Providers.of(getConfiguredSecureStoreClass()));
          }
        });
    modules.add(new GerritServerConfigModule());
    Guice.createInjector(modules).injectMembers(this);
    if (reindexThreads != -1 && !ReplicaUtil.isReplica(run.flags.cfg)) {
      List<String> indicesToReindex = new ArrayList<>();
      for (SchemaDefinitions<?> schemaDef : schemaDefs) {
        if (!indexStatus.exists(schemaDef.getName())) {
          indicesToReindex.add(schemaDef.getName());
        }
      }
      reindex(indicesToReindex);
    }
    start(run);
  }

  @Override
  protected List<String> getInstallPlugins() {
    return installPlugins;
  }

  @Override
  protected boolean installAllPlugins() {
    return installAllPlugins;
  }

  @Override
  protected ConsoleUI getConsoleUI() {
    return ConsoleUI.getInstance(batchMode);
  }

  @Override
  protected boolean getAutoStart() {
    return !noAutoStart;
  }

  @Override
  protected boolean getDeleteCaches() {
    return deleteCaches;
  }

  @Override
  protected boolean skipPlugins() {
    return skipPlugins;
  }

  @Override
  protected boolean isDev() {
    return dev;
  }

  @Override
  protected boolean skipAllDownloads() {
    return skipAllDownloads;
  }

  @Override
  protected List<String> getSkippedDownloads() {
    return skippedDownloads != null ? skippedDownloads : Collections.emptyList();
  }

  @Override
  protected String getSecureStoreLib() {
    return secureStoreLib;
  }

  void start(SiteRun run) throws Exception {
    if (reindexThreads != -1 && run.flags.autoStart) {
      if (HostPlatform.isWin32()) {
        System.err.println("Automatic startup not supported on Win32.");
      } else {
        startDaemon(run);
        if (!run.ui.isBatch()) {
          browser.open(PageLinks.ADMIN_PROJECTS);
        }
      }
    }
  }

  void startDaemon(SiteRun run) {
    String[] argv = {run.site.gerrit_sh.toAbsolutePath().toString(), "start"};
    Process proc;
    try {
      System.err.println("Executing " + argv[0] + " " + argv[1]);
      proc = Runtime.getRuntime().exec(argv);
    } catch (IOException e) {
      System.err.println("error: cannot start Gerrit: " + e.getMessage());
      return;
    }

    try {
      proc.getOutputStream().close();
    } catch (IOException e) {
      // Ignored
    }

    IoUtil.copyWithThread(proc.getInputStream(), System.err);
    IoUtil.copyWithThread(proc.getErrorStream(), System.err);

    for (; ; ) {
      try {
        int rc = proc.waitFor();
        if (rc != 0) {
          System.err.println("error: cannot start Gerrit: exit status " + rc);
        }
        break;
      } catch (InterruptedException e) {
        // retry
      }
    }
  }

  private void verifyInstallPluginList(ConsoleUI ui, List<PluginData> plugins) {
    if (nullOrEmpty(installPlugins)) {
      return;
    }
    Set<String> missing = Sets.newHashSet(installPlugins);
    plugins.stream().forEach(p -> missing.remove(p.name));
    if (!missing.isEmpty()) {
      ui.message("Cannot find plugin(s): %s\n", Joiner.on(", ").join(missing));
      listPlugins = true;
    }
  }

  private void reindex(List<String> indices) throws Exception {
    if (indices.isEmpty()) {
      return;
    }
    List<String> reindexArgs =
        Lists.newArrayList(
            "--site-path", getSitePath().toString(), "--threads", Integer.toString(reindexThreads));
    for (String index : indices) {
      reindexArgs.add("--index");
      reindexArgs.add(index);
    }
    if (showCacheStats) {
      reindexArgs.add("--show-cache-stats");
    }

    getConsoleUI()
        .message(String.format("Init complete, reindexing %s with:", String.join(",", indices)));
    getConsoleUI().message(" reindex " + reindexArgs.stream().collect(joining(" ")));
    Reindex reindexPgm = new Reindex();
    reindexPgm.main(reindexArgs.stream().toArray(String[]::new));
  }

  private static boolean nullOrEmpty(List<?> list) {
    return list == null || list.isEmpty();
  }
}
