// 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.common.flogger.FluentLogger;
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.ReviewDbFactory;
import com.google.gerrit.server.schema.ReviewDbSchemaUpdater;
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.List;
import java.util.Set;
import javax.sql.DataSource;

/** Initialize a new Gerrit installation. */
public class BaseInit extends SiteProgram {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  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) {
        names.removeIf(n -> !pluginsToInstall.contains(n));
      }
      return names;
    } catch (FileNotFoundException e) {
      logger.atWarning().log(
          "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 ReviewDbSchemaUpdater schemaUpdater;
    final SchemaFactory<ReviewDb> schema;
    final GitRepositoryManager repositoryManager;

    @Inject
    SiteRun(
        ConsoleUI ui,
        SitePaths site,
        InitFlags flags,
        ReviewDbSchemaUpdater schemaUpdater,
        @ReviewDbFactory 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;
  }
}
