// Copyright 2008 Google Inc.
//
// 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.gwtorm.jdbc;

import java.io.File;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
import javax.sql.DataSource;

/** A simple non-pooling DataSource representation. */
public class SimpleDataSource implements DataSource {
  private final Properties connectionInfo;
  private final String url;
  private final Driver driver;
  private PrintWriter logWriter;

  /**
   * Create a non-pooling data source.
   *
   * <p>The JDBC properties information must define at least <code>url</code> and <code>driver
   * </code>, but may also include driver specific properties such as <code>username</code> and
   * <code>password</code>.
   *
   * @param dbInfo JDBC connection information. The property table is copied.
   * @throws SQLException the driver class is not available through the current class loader.
   */
  public SimpleDataSource(final Properties dbInfo) throws SQLException {
    connectionInfo = new Properties();
    connectionInfo.putAll(dbInfo);

    url = (String) connectionInfo.remove("url");
    if (url == null) {
      throw new SQLException("Required property 'url' not defined");
    }

    final String driverName = (String) connectionInfo.remove("driver");
    final String classpath = (String) connectionInfo.remove("classpath");
    if (driverName != null) {
      ClassLoader cl = threadCL();
      if (classpath != null && classpath.length() > 0) {
        final List<URL> urls = new ArrayList<>();
        for (final String path : classpath.split(File.pathSeparator)) {
          try {
            urls.add(new URL(path));
          } catch (MalformedURLException e1) {
            final File f = new File(path);
            if (f.exists()) {
              try {
                urls.add(f.getAbsoluteFile().toURI().toURL());
              } catch (MalformedURLException e2) {
                throw badClasspath(classpath, e2);
              }
            } else {
              throw badClasspath(classpath, e1);
            }
          }
        }
        cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), cl);
      }
      driver = loadDriver(driverName, cl);
    } else {
      driver = null;
    }

    logWriter = new PrintWriter(System.out);
  }

  private static SQLException badClasspath(final String classpath, final MalformedURLException e1) {
    final SQLException sqle;
    sqle = new SQLException("Invalid driver classpath " + classpath);
    sqle.initCause(e1);
    return sqle;
  }

  @Override
  public Connection getConnection() throws SQLException {
    if (driver != null) {
      return driver.connect(url, connectionInfo);
    }
    return DriverManager.getConnection(url, connectionInfo);
  }

  @Override
  public Connection getConnection(String user, String password) throws SQLException {
    if (driver != null) {
      final Properties info = new Properties(connectionInfo);
      if (user != null) {
        info.put("user", user);
      }
      if (password != null) {
        info.put("password", password);
      }
      return driver.connect(url, info);
    }
    return DriverManager.getConnection(url, user, password);
  }

  @Override
  public PrintWriter getLogWriter() {
    return logWriter;
  }

  @Override
  public void setLogWriter(final PrintWriter out) {
    logWriter = out;
  }

  @Override
  public int getLoginTimeout() {
    return 0;
  }

  @Override
  public void setLoginTimeout(int seconds) {}

  @Override
  public boolean isWrapperFor(Class<?> iface) {
    return false;
  }

  @Override
  public <T> T unwrap(Class<T> iface) throws SQLException {
    throw new SQLException(getClass().getName() + " wraps nothing");
  }

  @Override
  public Logger getParentLogger() throws SQLFeatureNotSupportedException {
    throw new SQLFeatureNotSupportedException();
  }

  private static synchronized Driver loadDriver(final String driver, final ClassLoader loader)
      throws SQLException {
    // I've seen some drivers (*cough* Informix *cough*) which won't load
    // on multiple threads at the same time. Forcing our code to synchronize
    // around loading the driver ensures we won't ever ask for the same driver
    // to initialize from different threads. Of course that could still happen
    // in other parts of the same JVM, but its quite unlikely.
    //
    try {
      return (Driver) Class.forName(driver, true, loader).newInstance();
    } catch (Throwable err) {
      final SQLException e;
      e = new SQLException("Driver class " + driver + " not available");
      e.initCause(err);
      throw e;
    }
  }

  private static ClassLoader threadCL() {
    try {
      return Thread.currentThread().getContextClassLoader();
    } catch (SecurityException e) {
      return SimpleDataSource.class.getClassLoader();
    }
  }
}
