// Copyright (C) 2013 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 static com.google.gerrit.reviewdb.server.ReviewDbUtil.unwrapDb;
import static com.google.gerrit.server.schema.DataSourceProvider.Context.SINGLE_USER;
import static com.google.inject.Scopes.SINGLETON;
import static com.google.inject.Stage.PRODUCTION;

import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.gerrit.common.Die;
import com.google.gerrit.common.IoUtil;
import com.google.gerrit.metrics.DisabledMetricMaker;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.InstallAllPlugins;
import com.google.gerrit.pgm.init.api.InstallPlugins;
import com.google.gerrit.pgm.init.api.LibraryDownload;
import com.google.gerrit.pgm.init.index.IndexManagerOnInit;
import com.google.gerrit.pgm.init.index.elasticsearch.ElasticIndexModuleOnInit;
import com.google.gerrit.pgm.init.index.lucene.LuceneIndexModuleOnInit;
import com.google.gerrit.pgm.util.SiteProgram;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.GerritServerConfigModule;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.plugins.JarScanner;
import com.google.gerrit.server.schema.SchemaUpdater;
import com.google.gerrit.server.schema.UpdateUI;
import com.google.gerrit.server.securestore.SecureStore;
import com.google.gerrit.server.securestore.SecureStoreClassName;
import com.google.gerrit.server.securestore.SecureStoreProvider;
import com.google.gwtorm.jdbc.JdbcExecutor;
import com.google.gwtorm.jdbc.JdbcSchema;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.gwtorm.server.StatementExecutor;
import com.google.inject.AbstractModule;
import com.google.inject.CreationException;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.Message;
import com.google.inject.util.Providers;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Initialize a new Gerrit installation. */
public class BaseInit extends SiteProgram {
  private static final Logger log = LoggerFactory.getLogger(BaseInit.class);

  private final boolean standalone;
  private final boolean initDb;
  protected final PluginsDistribution pluginsDistribution;
  private final List<String> pluginsToInstall;

  private Injector sysInjector;

  protected BaseInit(PluginsDistribution pluginsDistribution, List<String> pluginsToInstall) {
    this.standalone = true;
    this.initDb = true;
    this.pluginsDistribution = pluginsDistribution;
    this.pluginsToInstall = pluginsToInstall;
  }

  public BaseInit(
      Path sitePath,
      boolean standalone,
      boolean initDb,
      PluginsDistribution pluginsDistribution,
      List<String> pluginsToInstall) {
    this(sitePath, null, standalone, initDb, pluginsDistribution, pluginsToInstall);
  }

  public BaseInit(
      Path sitePath,
      final Provider<DataSource> dsProvider,
      boolean standalone,
      boolean initDb,
      PluginsDistribution pluginsDistribution,
      List<String> pluginsToInstall) {
    super(sitePath, dsProvider);
    this.standalone = standalone;
    this.initDb = initDb;
    this.pluginsDistribution = pluginsDistribution;
    this.pluginsToInstall = pluginsToInstall;
  }

  @Override
  public int run() throws Exception {
    final SiteInit init = createSiteInit();
    if (beforeInit(init)) {
      return 0;
    }

    init.flags.autoStart = getAutoStart() && init.site.isNew;
    init.flags.dev = isDev() && init.site.isNew;
    init.flags.skipPlugins = skipPlugins();
    init.flags.deleteCaches = getDeleteCaches();
    init.flags.isNew = init.site.isNew;

    final SiteRun run;
    try {
      init.initializer.run();
      init.flags.deleteOnFailure = false;

      Injector sysInjector = createSysInjector(init);
      IndexManagerOnInit indexManager = sysInjector.getInstance(IndexManagerOnInit.class);
      try {
        indexManager.start();
        run = createSiteRun(init);
        run.upgradeSchema();

        init.initializer.postRun(sysInjector);
      } finally {
        indexManager.stop();
      }
    } catch (Exception | Error failure) {
      if (init.flags.deleteOnFailure) {
        recursiveDelete(getSitePath());
      }
      throw failure;
    }

    System.err.println("Initialized " + getSitePath().toRealPath().normalize());
    afterInit(run);
    return 0;
  }

  protected boolean skipPlugins() {
    return false;
  }

  protected String getSecureStoreLib() {
    return null;
  }

  protected boolean skipAllDownloads() {
    return false;
  }

  protected List<String> getSkippedDownloads() {
    return Collections.emptyList();
  }

  /**
   * Invoked before site init is called.
   *
   * @param init initializer instance.
   * @throws Exception
   */
  protected boolean beforeInit(SiteInit init) throws Exception {
    return false;
  }

  /**
   * Invoked after site init is called.
   *
   * @param run completed run instance.
   * @throws Exception
   */
  protected void afterInit(SiteRun run) throws Exception {}

  protected List<String> getInstallPlugins() {
    try {
      if (pluginsToInstall != null && pluginsToInstall.isEmpty()) {
        return Collections.emptyList();
      }
      List<String> names = pluginsDistribution.listPluginNames();
      if (pluginsToInstall != null) {
        for (Iterator<String> i = names.iterator(); i.hasNext(); ) {
          String n = i.next();
          if (!pluginsToInstall.contains(n)) {
            i.remove();
          }
        }
      }
      return names;
    } catch (FileNotFoundException e) {
      log.warn("Couldn't find distribution archive location. No plugin will be installed");
      return null;
    }
  }

  protected boolean installAllPlugins() {
    return false;
  }

  protected boolean getAutoStart() {
    return false;
  }

  public static class SiteInit {
    public final SitePaths site;
    final InitFlags flags;
    final ConsoleUI ui;
    final SitePathInitializer initializer;

    @Inject
    SiteInit(
        final SitePaths site,
        final InitFlags flags,
        final ConsoleUI ui,
        final SitePathInitializer initializer) {
      this.site = site;
      this.flags = flags;
      this.ui = ui;
      this.initializer = initializer;
    }
  }

  private SiteInit createSiteInit() {
    final ConsoleUI ui = getConsoleUI();
    final Path sitePath = getSitePath();
    final List<Module> m = new ArrayList<>();
    final SecureStoreInitData secureStoreInitData = discoverSecureStoreClass();
    final String currentSecureStoreClassName = getConfiguredSecureStoreClass();

    if (secureStoreInitData != null
        && currentSecureStoreClassName != null
        && !currentSecureStoreClassName.equals(secureStoreInitData.className)) {
      String err =
          String.format(
              "Different secure store was previously configured: %s. "
                  + "Use SwitchSecureStore program to switch between implementations.",
              currentSecureStoreClassName);
      throw die(err);
    }

    m.add(new GerritServerConfigModule());
    m.add(new InitModule(standalone, initDb));
    m.add(
        new AbstractModule() {
          @Override
          protected void configure() {
            bind(ConsoleUI.class).toInstance(ui);
            bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath);
            List<String> plugins =
                MoreObjects.firstNonNull(getInstallPlugins(), new ArrayList<String>());
            bind(new TypeLiteral<List<String>>() {})
                .annotatedWith(InstallPlugins.class)
                .toInstance(plugins);
            bind(new TypeLiteral<Boolean>() {})
                .annotatedWith(InstallAllPlugins.class)
                .toInstance(installAllPlugins());
            bind(PluginsDistribution.class).toInstance(pluginsDistribution);

            String secureStoreClassName;
            if (secureStoreInitData != null) {
              secureStoreClassName = secureStoreInitData.className;
            } else {
              secureStoreClassName = currentSecureStoreClassName;
            }
            if (secureStoreClassName != null) {
              ui.message("Using secure store: %s\n", secureStoreClassName);
            }
            bind(SecureStoreInitData.class).toProvider(Providers.of(secureStoreInitData));
            bind(String.class)
                .annotatedWith(SecureStoreClassName.class)
                .toProvider(Providers.of(secureStoreClassName));
            bind(SecureStore.class).toProvider(SecureStoreProvider.class).in(SINGLETON);
            bind(new TypeLiteral<List<String>>() {})
                .annotatedWith(LibraryDownload.class)
                .toInstance(getSkippedDownloads());
            bind(Boolean.class).annotatedWith(LibraryDownload.class).toInstance(skipAllDownloads());

            bind(MetricMaker.class).to(DisabledMetricMaker.class);
          }
        });

    try {
      return Guice.createInjector(PRODUCTION, m).getInstance(SiteInit.class);
    } catch (CreationException ce) {
      final Message first = ce.getErrorMessages().iterator().next();
      Throwable why = first.getCause();

      if (why instanceof Die) {
        throw (Die) why;
      }

      final StringBuilder buf = new StringBuilder(ce.getMessage());
      while (why != null) {
        buf.append("\n");
        buf.append(why.getMessage());
        why = why.getCause();
        if (why != null) {
          buf.append("\n  caused by ");
        }
      }
      throw die(buf.toString(), new RuntimeException("InitInjector failed", ce));
    }
  }

  protected ConsoleUI getConsoleUI() {
    return ConsoleUI.getInstance(false);
  }

  private SecureStoreInitData discoverSecureStoreClass() {
    String secureStore = getSecureStoreLib();
    if (Strings.isNullOrEmpty(secureStore)) {
      return null;
    }

    Path secureStoreLib = Paths.get(secureStore);
    if (!Files.exists(secureStoreLib)) {
      throw new InvalidSecureStoreException(String.format("File %s doesn't exist", secureStore));
    }
    try (JarScanner scanner = new JarScanner(secureStoreLib)) {
      List<String> secureStores = scanner.findSubClassesOf(SecureStore.class);
      if (secureStores.isEmpty()) {
        throw new InvalidSecureStoreException(
            String.format(
                "Cannot find class implementing %s interface in %s",
                SecureStore.class.getName(), secureStore));
      }
      if (secureStores.size() > 1) {
        throw new InvalidSecureStoreException(
            String.format(
                "%s has more that one implementation of %s interface",
                secureStore, SecureStore.class.getName()));
      }
      IoUtil.loadJARs(secureStoreLib);
      return new SecureStoreInitData(secureStoreLib, secureStores.get(0));
    } catch (IOException e) {
      throw new InvalidSecureStoreException(String.format("%s is not a valid jar", secureStore));
    }
  }

  public static class SiteRun {
    public final ConsoleUI ui;
    public final SitePaths site;
    public final InitFlags flags;
    final SchemaUpdater schemaUpdater;
    final SchemaFactory<ReviewDb> schema;
    final GitRepositoryManager repositoryManager;

    @Inject
    SiteRun(
        ConsoleUI ui,
        SitePaths site,
        InitFlags flags,
        SchemaUpdater schemaUpdater,
        SchemaFactory<ReviewDb> schema,
        GitRepositoryManager repositoryManager) {
      this.ui = ui;
      this.site = site;
      this.flags = flags;
      this.schemaUpdater = schemaUpdater;
      this.schema = schema;
      this.repositoryManager = repositoryManager;
    }

    void upgradeSchema() throws OrmException {
      final List<String> pruneList = new ArrayList<>();
      schemaUpdater.update(
          new UpdateUI() {
            @Override
            public void message(String message) {
              System.err.println(message);
              System.err.flush();
            }

            @Override
            public boolean yesno(boolean defaultValue, String message) {
              return ui.yesno(defaultValue, message);
            }

            @Override
            public void waitForUser() {
              ui.waitForUser();
            }

            @Override
            public String readString(
                String defaultValue, Set<String> allowedValues, String message) {
              return ui.readString(defaultValue, allowedValues, message);
            }

            @Override
            public boolean isBatch() {
              return ui.isBatch();
            }

            @Override
            public void pruneSchema(StatementExecutor e, List<String> prune) {
              for (String p : prune) {
                if (!pruneList.contains(p)) {
                  pruneList.add(p);
                }
              }
            }
          });

      if (!pruneList.isEmpty()) {
        StringBuilder msg = new StringBuilder();
        msg.append("Execute the following SQL to drop unused objects:\n");
        msg.append("\n");
        for (String sql : pruneList) {
          msg.append("  ");
          msg.append(sql);
          msg.append(";\n");
        }

        if (ui.isBatch()) {
          System.err.print(msg);
          System.err.flush();

        } else if (ui.yesno(true, "%s\nExecute now", msg)) {
          try (JdbcSchema db = (JdbcSchema) unwrapDb(schema.open());
              JdbcExecutor e = new JdbcExecutor(db)) {
            for (String sql : pruneList) {
              e.execute(sql);
            }
          }
        }
      }
    }
  }

  private SiteRun createSiteRun(SiteInit init) {
    return createSysInjector(init).getInstance(SiteRun.class);
  }

  private Injector createSysInjector(SiteInit init) {
    if (sysInjector == null) {
      final List<Module> modules = new ArrayList<>();
      modules.add(
          new AbstractModule() {
            @Override
            protected void configure() {
              bind(ConsoleUI.class).toInstance(init.ui);
              bind(InitFlags.class).toInstance(init.flags);
            }
          });
      Injector dbInjector = createDbInjector(SINGLE_USER);
      switch (IndexModule.getIndexType(dbInjector)) {
        case LUCENE:
          modules.add(new LuceneIndexModuleOnInit());
          break;
        case ELASTICSEARCH:
          modules.add(new ElasticIndexModuleOnInit());
          break;
        default:
          throw new IllegalStateException("unsupported index.type");
      }
      sysInjector = dbInjector.createChildInjector(modules);
    }
    return sysInjector;
  }

  private static void recursiveDelete(Path path) {
    final String msg = "warn: Cannot remove ";
    try {
      Files.walkFileTree(
          path,
          new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path f, BasicFileAttributes attrs) throws IOException {
              try {
                Files.delete(f);
              } catch (IOException e) {
                System.err.println(msg + f);
              }
              return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException err) {
              try {
                // Previously warned if err was not null; if dir is not empty as a
                // result, will cause an error that will be logged below.
                Files.delete(dir);
              } catch (IOException e) {
                System.err.println(msg + dir);
              }
              return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path f, IOException e) {
              System.err.println(msg + f);
              return FileVisitResult.CONTINUE;
            }
          });
    } catch (IOException e) {
      System.err.println(msg + path);
    }
  }

  protected boolean isDev() {
    return false;
  }

  protected boolean getDeleteCaches() {
    return false;
  }
}
