// 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.server.schema;

import static com.google.gerrit.server.config.ConfigUtil.getEnum;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;

import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtorm.jdbc.SimpleDataSource;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
import com.google.inject.Singleton;

import org.apache.commons.dbcp.BasicDataSource;
import org.eclipse.jgit.lib.Config;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

/** Provides access to the DataSource. */
@Singleton
public final class DataSourceProvider implements Provider<DataSource>,
    LifecycleListener {
  private final DataSource ds;

  @Inject
  DataSourceProvider(final SitePaths site,
      @GerritServerConfig final Config cfg, Context ctx) {
    ds = open(site, cfg, ctx);
  }

  @Override
  public synchronized DataSource get() {
    return ds;
  }

  @Override
  public void start() {
  }

  @Override
  public synchronized void stop() {
    if (ds instanceof BasicDataSource) {
      try {
        ((BasicDataSource) ds).close();
      } catch (SQLException e) {
        // Ignore the close failure.
      }
    }
  }

  public static enum Context {
    SINGLE_USER, MULTI_USER;
  }

  public static enum Type {
    H2, POSTGRESQL, MYSQL, JDBC;
  }

  private DataSource open(final SitePaths site, final Config cfg,
      final Context context) {
    Type type = getEnum(cfg, "database", null, "type", Type.values(), null);
    String driver = optional(cfg, "driver");
    String url = optional(cfg, "url");
    String username = optional(cfg, "username");
    String password = optional(cfg, "password");

    if (url == null || url.isEmpty()) {
      if (type == null) {
        type = Type.H2;
      }

      switch (type) {
        case H2: {
          String database = optional(cfg, "database");
          if (database == null || database.isEmpty()) {
            database = "db/ReviewDB";
          }
          File db = site.resolve(database);
          try {
            db = db.getCanonicalFile();
          } catch (IOException e) {
            db = db.getAbsoluteFile();
          }
          url = "jdbc:h2:" + db.toURI().toString();
          break;
        }

        case POSTGRESQL: {
          final StringBuilder b = new StringBuilder();
          b.append("jdbc:postgresql://");
          b.append(hostname(optional(cfg, "hostname")));
          b.append(port(optional(cfg, "port")));
          b.append("/");
          b.append(required(cfg, "database"));
          url = b.toString();
          break;
        }

        case MYSQL: {
          final StringBuilder b = new StringBuilder();
          b.append("jdbc:mysql://");
          b.append(hostname(optional(cfg, "hostname")));
          b.append(port(optional(cfg, "port")));
          b.append("/");
          b.append(required(cfg, "database"));
          url = b.toString();
          break;
        }

        case JDBC:
          driver = required(cfg, "driver");
          url = required(cfg, "url");
          break;

        default:
          throw new IllegalArgumentException(type + " not supported");
      }
    }

    if (driver == null || driver.isEmpty()) {
      if (url.startsWith("jdbc:h2:")) {
        driver = "org.h2.Driver";

      } else if (url.startsWith("jdbc:postgresql:")) {
        driver = "org.postgresql.Driver";

      } else if (url.startsWith("jdbc:mysql:")) {
        driver = "com.mysql.jdbc.Driver";

      } else {
        throw new IllegalArgumentException("database.driver must be set");
      }
    }

    boolean usePool;
    if (url.startsWith("jdbc:mysql:")) {
      // MySQL has given us trouble with the connection pool,
      // sometimes the backend disconnects and the pool winds
      // up with a stale connection. Fortunately opening up
      // a new MySQL connection is usually very fast.
      //
      usePool = false;
    } else {
      usePool = true;
    }
    usePool = cfg.getBoolean("database", "connectionpool", usePool);
    if (context == Context.SINGLE_USER) {
      usePool = false;
    }

    if (usePool) {
      final BasicDataSource ds = new BasicDataSource();
      ds.setDriverClassName(driver);
      ds.setUrl(url);
      if (username != null && !username.isEmpty()) {
        ds.setUsername(username);
      }
      if (password != null && !password.isEmpty()) {
        ds.setPassword(password);
      }
      ds.setMaxActive(cfg.getInt("database", "poollimit", 8));
      ds.setMinIdle(cfg.getInt("database", "poolminidle", 4));
      ds.setMaxIdle(cfg.getInt("database", "poolmaxidle", 4));
      ds.setMaxWait(ConfigUtil.getTimeUnit(cfg, "database", null,
          "poolmaxwait", MILLISECONDS.convert(30, SECONDS), MILLISECONDS));
      ds.setInitialSize(ds.getMinIdle());
      return ds;

    } else {
      // Don't use the connection pool.
      //
      try {
        final Properties p = new Properties();
        p.setProperty("driver", driver);
        p.setProperty("url", url);
        if (username != null) {
          p.setProperty("user", username);
        }
        if (password != null) {
          p.setProperty("password", password);
        }
        return new SimpleDataSource(p);
      } catch (SQLException se) {
        throw new ProvisionException("Database unavailable", se);
      }
    }
  }

  private static String hostname(String hostname) {
    if (hostname == null || hostname.isEmpty()) {
      hostname = "localhost";

    } else if (hostname.contains(":") && !hostname.startsWith("[")) {
      hostname = "[" + hostname + "]";
    }
    return hostname;
  }

  private static String port(String port) {
    if (port != null && !port.isEmpty()) {
      return ":" + port;
    }
    return "";
  }

  private static String optional(final Config config, final String name) {
    return config.getString("database", null, name);
  }

  private static String required(final Config config, final String name) {
    final String v = optional(config, name);
    if (v == null || "".equals(v)) {
      throw new IllegalArgumentException("No database." + name + " configured");
    }
    return v;
  }
}
