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

import static com.google.gerrit.pgm.init.InitUtil.die;
import static com.google.gerrit.pgm.init.InitUtil.username;
import static com.google.gerrit.pgm.util.DataSourceProvider.Type.H2;

import com.google.gerrit.pgm.util.ConsoleUI;
import com.google.gerrit.pgm.util.DataSourceProvider;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import java.io.File;

/** Initialize the {@code database} configuration section. */
@Singleton
class InitDatabase implements InitStep {
  private final ConsoleUI ui;
  private final SitePaths site;
  private final Libraries libraries;
  private final Section database;

  @Inject
  InitDatabase(final ConsoleUI ui, final SitePaths site, final Libraries libraries,
      final Section.Factory sections) {
    this.ui = ui;
    this.site = site;
    this.libraries = libraries;
    this.database = sections.get("database");
  }

  public void run() {
    ui.header("SQL Database");

    final DataSourceProvider.Type db_type =
        database.select("Database server type", "type", H2);

    switch (db_type) {
      case MYSQL:
        libraries.mysqlDriver.downloadRequired();
        break;
    }

    final boolean userPassAuth;
    switch (db_type) {
      case H2: {
        userPassAuth = false;
        String path = database.get("database");
        if (path == null) {
          path = "db/ReviewDB";
          database.set("database", path);
        }
        File db = site.resolve(path);
        if (db == null) {
          throw die("database.database must be supplied for H2");
        }
        db = db.getParentFile();
        if (!db.exists() && !db.mkdirs()) {
          throw die("cannot create database.database " + db.getAbsolutePath());
        }
        break;
      }

      case JDBC: {
        userPassAuth = true;
        database.string("Driver class name", "driver", null);
        database.string("URL", "url", null);
        break;
      }

      case POSTGRES:
      case POSTGRESQL:
      case MYSQL: {
        userPassAuth = true;
        final String defPort = "(" + db_type.toString() + " default)";
        database.string("Server hostname", "hostname", "localhost");
        database.string("Server port", "port", defPort, true);
        database.string("Database name", "database", "reviewdb");
        break;
      }

      default:
        throw die("internal bug, database " + db_type + " not supported");
    }

    if (userPassAuth) {
      database.string("Database username", "username", username());
      database.password("username", "password");
    }
  }
}
