/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.internal.datasource;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

import org.apache.logging.log4j.Logger;

import org.apache.geode.internal.ClassPathLoader;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * GemFireBasicDataSource extends AbstractDataSource. This is a datasource class which provides
 * connections. fromthe databse without any pooling.
 *
 */
public class GemFireBasicDataSource extends AbstractDataSource {
  private static final Logger logger = LogService.getLogger();

  private static final long serialVersionUID = -4010116024816908360L;

  /** Creates a new instance of BaseDataSource */
  protected transient volatile Driver driverObject = null;

  /**
   * Place holder for abstract method isWrapperFor(java.lang.Class) in java.sql.Wrapper required by
   * jdk 1.6
   *
   * @param iface - a Class defining an interface.
   */
  @Override
  public boolean isWrapperFor(Class iface) throws SQLException {
    return true;
  }

  /**
   * Place holder for abstract method java.lang Object unwrap(java.lang.Class) in java.sql.Wrapper
   * required by jdk 1.6
   *
   * @param iface - a Class defining an interface.
   * @return java.lang.Object
   */
  @Override
  public Object unwrap(Class iface) throws SQLException {
    return iface;
  }

  /**
   * Creates a new instance of GemFireBasicDataSource
   *
   * @param configs The ConfiguredDataSourceProperties containing the datasource properties.
   */
  public GemFireBasicDataSource(ConfiguredDataSourceProperties configs) throws SQLException {
    super(configs);
    driverObject = loadDriver();
  }

  /**
   * Implementation of datasource interface function. This method is used to get the connection from
   * the database. Default user name and password will be used.
   *
   * @return ???
   */
  @Override
  public Connection getConnection() throws SQLException {
    // Asif : In case the user is requesting the
    // connection without username & password
    // we should just return the desired connection
    Connection connection = null;
    Driver localDriverRef = driverObject;
    if (localDriverRef == null) {
      synchronized (this) {
        localDriverRef = driverObject;
        if (localDriverRef == null) {
          localDriverRef = loadDriver();
          driverObject = localDriverRef;
        }
      }
    }

    if (url != null) {
      Properties props = new Properties();

      // If no default username or password is specified don't add these properties - the user may
      // be connecting to a system which does not require authentication
      if (user != null) {
        props.put("user", user);
      }

      // check for password separately from username - some drivers may throw different error
      // messages we want to capture
      if (password != null) {
        props.put("password", password);
      }
      connection = driverObject.connect(url, props);
    } else {
      String exception =
          "GemFireBasicDataSource::getConnection:Url for the DataSource not available";
      logger.info(exception);
      throw new SQLException(exception);
    }
    return connection;
  }

  /**
   * Implementation of datasource function. This method is used to get the connection. The specified
   * user name and passowrd will be used.
   *
   * @param clUsername The username for the database connection.
   * @param clPassword The password for the database connection.
   */
  @Override
  public Connection getConnection(String clUsername, String clPassword) throws SQLException {
    // First Autheticate the user
    checkCredentials(clUsername, clPassword);
    return getConnection();
  }

  private Driver loadDriver() throws SQLException {
    try {
      if (jdbcDriver != null && jdbcDriver.length() > 0) {
        return loadDriverUsingClassName();
      } else {
        return loadDriverUsingURL();
      }
    } catch (Exception ex) {
      String msg =
          "An Exception was caught while trying to load the driver. %s";
      String msgArg = ex.getLocalizedMessage();
      logger.error(String.format(msg, msgArg), ex);
      throw new SQLException(String.format(msg, msgArg));
    }
  }

  private Driver loadDriverUsingURL() throws SQLException {
    return DriverManager.getDriver(this.url);
  }

  private Driver loadDriverUsingClassName()
      throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    Class<?> driverClass = ClassPathLoader.getLatest().forName(jdbcDriver);
    return (Driver) driverClass.newInstance();
  }
}
