// Copyright (C) 2015 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.googlesource.gerrit.plugins.verifystatus.init;

import static com.google.inject.Scopes.SINGLETON;
import static com.google.inject.Stage.PRODUCTION;

import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.pgm.init.api.Section;
import com.google.gerrit.server.config.SitePaths;
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.Binding;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import com.googlesource.gerrit.plugins.verifystatus.server.CiDb;
import com.googlesource.gerrit.plugins.verifystatus.server.schema.CiDataSourceModule;
import com.googlesource.gerrit.plugins.verifystatus.server.schema.CiDataSourceProvider;
import com.googlesource.gerrit.plugins.verifystatus.server.schema.CiDataSourceType;
import com.googlesource.gerrit.plugins.verifystatus.server.schema.CiDataSourceTypeGuesser;
import com.googlesource.gerrit.plugins.verifystatus.server.schema.CiDatabaseModule;
import com.googlesource.gerrit.plugins.verifystatus.server.schema.CurrentSchemaVersion;
import com.googlesource.gerrit.plugins.verifystatus.server.schema.SchemaVersion;
import com.googlesource.gerrit.plugins.verifystatus.server.schema.UpdateUI;
import java.lang.annotation.Annotation;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.sql.DataSource;

@Singleton
public class InitPlugin implements InitStep {
  private final ConsoleUI ui;
  private final SitePaths site;
  private final Section configSection;
  private final Injector parent;
  private SchemaFactory<CiDb> dbFactory;
  private Provider<SchemaVersion> updater;

  @Inject
  InitPlugin(
      Section.Factory sections,
      @PluginName String pluginName,
      ConsoleUI ui,
      SitePaths site,
      Injector parent) {
    this.ui = ui;
    this.site = site;
    this.configSection = sections.get("plugin", pluginName);
    this.parent = parent;
  }

  @Override
  public void run() throws Exception {
    ui.header("SQL Database for CI plugin");

    Set<String> allowedValues = Sets.newTreeSet();
    Injector i = Guice.createInjector(PRODUCTION, new DatabaseConfigModule(site));

    List<Binding<DatabaseConfigInitializer>> dbConfigBindings =
        i.findBindingsByType(new TypeLiteral<DatabaseConfigInitializer>() {});
    for (Binding<DatabaseConfigInitializer> binding : dbConfigBindings) {
      Annotation annotation = binding.getKey().getAnnotation();
      if (annotation instanceof Named) {
        allowedValues.add(((Named) annotation).value());
      }
    }

    if (!Strings.isNullOrEmpty(configSection.get("dbUrl"))
        && Strings.isNullOrEmpty(configSection.get("dbType"))) {
      configSection.set("dbType", "h2");
    }

    String dbType = configSection.select("Database server type", "dbType", "h2", allowedValues);

    DatabaseConfigInitializer dci =
        i.getInstance(Key.get(DatabaseConfigInitializer.class, Names.named(dbType.toLowerCase())));

    /**
     * TODO(davido): We probably don't need that, as CI database would be from the same type as
     * ReviewDb. So we expect that the needed libraries were already installed.
     *
     * <p>if (dci instanceof MySqlInitializer) { libraries.mysqlDriver.downloadRequired(); } else if
     * (dci instanceof OracleInitializer) { libraries.oracleDriver.downloadRequired(); } else if
     * (dci instanceof DB2Initializer) { libraries.db2Driver.downloadRequired(); }
     */
    dci.initConfig(configSection);
  }

  @Override
  public void postRun() throws Exception {
    Injector i = buildInjector(parent);
    updater = i.getProvider(SchemaVersion.class);
    this.dbFactory = i.getInstance(Key.get(new TypeLiteral<SchemaFactory<CiDb>>() {}));
    upgradeSchema();
  }

  private Injector buildInjector(final Injector parent) {
    List<Module> modules = new ArrayList<>();

    modules.add(
        new LifecycleModule() {
          @Override
          protected void configure() {
            // For bootstrap we need to retrieve the ds type first
            CiDataSourceTypeGuesser guesser =
                parent
                    .createChildInjector(new CiDataSourceModule())
                    .getInstance(Key.get(CiDataSourceTypeGuesser.class));

            // For the ds type we retrieve the underlying implementation
            CiDataSourceType dst =
                parent
                    .createChildInjector(new CiDataSourceModule())
                    .getInstance(
                        Key.get(
                            CiDataSourceType.class, Names.named(guesser.guessDataSourceType())));

            // Bind the type to the retrieved instance
            bind(CiDataSourceType.class).toInstance(dst);
            bind(CiDataSourceProvider.Context.class)
                .toInstance(CiDataSourceProvider.Context.MULTI_USER);
            bind(Key.get(DataSource.class, Names.named("CiDb")))
                .toProvider(CiDataSourceProvider.class)
                .in(SINGLETON);

            listener().to(CiDataSourceProvider.class);
          }
        });

    modules.add(new CiDatabaseModule());

    modules.add(
        new AbstractModule() {
          @Override
          protected void configure() {
            bind(SchemaVersion.class).to(SchemaVersion.C);
          }
        });

    return parent.createChildInjector(modules);
  }

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

          @Override
          public boolean yesno(boolean def, String msg) {
            return ui.yesno(def, msg);
          }

          @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) dbFactory.open();
            JdbcExecutor e = new JdbcExecutor(db)) {
          for (String sql : pruneList) {
            e.execute(sql);
          }
        }
      }
    }
  }

  public void update(UpdateUI ui) throws OrmException {
    try (CiDb db = dbFactory.open()) {
      SchemaVersion u = updater.get();
      CurrentSchemaVersion version = getSchemaVersion(db);
      if (version == null) {
        try (JdbcExecutor e = new JdbcExecutor((JdbcSchema) db)) {
          ((JdbcSchema) db).updateSchema(e);
        }
        final CurrentSchemaVersion sVer = CurrentSchemaVersion.create();
        sVer.versionNbr = SchemaVersion.getBinaryVersion();
        db.schemaVersion().insert(Collections.singleton(sVer));
      } else {
        try {
          u.check(ui, version, db);
        } catch (SQLException e) {
          throw new OrmException("Cannot upgrade schema", e);
        }
      }
    }
  }

  private CurrentSchemaVersion getSchemaVersion(CiDb db) {
    try {
      return db.schemaVersion().get(new CurrentSchemaVersion.Key());
    } catch (OrmException e) {
      return null;
    }
  }
}
