// 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.reviewdb.client.CurrentSchemaVersion;
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.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;
    }
  }
}
