/*
 *
 * Derby - Class org.apache.derbyTesting.junit.JDBCDataSource
 *
 * 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.derbyTesting.junit;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;

import junit.framework.Assert;

/**
 * Utility methods related to JDBC DataSource objects.
 * J2EEDataSource exists to return XA and connection pooling data sources.
 * 
 * @see J2EEDataSource
 */
public class JDBCDataSource {
    
    /**
     * Return a new DataSource corresponding to the current
     * configuration. The getConnection() method will return
     * a connection identical to TestConfiguration.openDefaultConnection().
     */
    public static javax.sql.DataSource getDataSource()
    {
        return getDataSource(TestConfiguration.getCurrent(), (HashMap) null);
    }
    
    /**
     * Return a new DataSource corresponding to the current
     * configuration except that the database name is different.
     */
    public static javax.sql.DataSource getDataSource(String dbName)
    {
        // default DataSource
        javax.sql.DataSource ds = getDataSource();
        
        // Override the database name
        setBeanProperty(ds, "databaseName", dbName);
        
        return ds;
    }
    
    /**
     * Return a DataSource corresponding to one
     * of the logical databases in the current configuration.
     */
    public static javax.sql.DataSource
         getDataSourceLogical(String logicalDatabasename)
    {
        // default DataSource
        javax.sql.DataSource ds = getDataSource();
        
        TestConfiguration current = TestConfiguration.getCurrent();
        String physicalName =
            current.getPhysicalDatabaseName(logicalDatabasename);
        
        // Override the database name
        setBeanProperty(ds, "databaseName", physicalName);
        
        return ds;
    }
    
    /**
     * Create a new DataSource object setup from the passed in TestConfiguration.
     * The getConnection() method will return a connection identical to
     * TestConfiguration.openDefaultConnection().
     */
    static javax.sql.DataSource getDataSource(TestConfiguration config,
            HashMap beanProperties)
    {
        return (javax.sql.DataSource) getDataSource(config,
            beanProperties, config.getJDBCClient().getDataSourceClassName());
    }

    /**
     * Create a new DataSource object setup from the passed in
     * TestConfiguration using the received properties and data
     * source class name.
     */
    static Object getDataSource(TestConfiguration config,
        HashMap beanProperties, String dsClassName)
    {
        if (beanProperties == null)
             beanProperties = getDataSourceProperties(config);
        
        return getDataSourceObject(dsClassName,
            beanProperties);
    }
    
    /**
     * Create a HashMap with the set of Derby DataSource
     * Java bean properties corresponding to the configuration.
     */
    static HashMap<String, Object> getDataSourceProperties(TestConfiguration config)
    {
        HashMap<String, Object> beanProperties = new HashMap<String, Object>();
        
        if (!config.getJDBCClient().isEmbedded()) {
            beanProperties.put("serverName", config.getHostName());
            beanProperties.put("portNumber", config.getPort());
        }
        
        beanProperties.put("databaseName", config.getDefaultDatabaseName());
        beanProperties.put("user", config.getUserName());
        beanProperties.put("password", config.getUserPassword());

        String attributes = config.getConnectionAttributesString();
        if (attributes != null) {
            beanProperties.put("connectionAttributes", attributes);
        }

        return beanProperties;
    }
    
    /**
     * Return a DataSource object of the passed in type
     * configured with the passed in Java bean properties.
     * This will actually work with any object that has Java bean
     * setter methods.
     * <BR>
     * If a thread context class loader exists then it is used
     * to try and load the class.
     */
    static javax.sql.DataSource getDataSourceObject(String classname, HashMap beanProperties)
    {
        ClassLoader contextLoader = AccessController.doPrivileged(
                new PrivilegedAction<ClassLoader>() {
            public ClassLoader run() {
                return Thread.currentThread().getContextClassLoader();
            }
        });
    
        try {
            javax.sql.DataSource ds = null;
            if (contextLoader != null)
            {
                try {
                    Class<?> clazz = Class.forName(classname, true, contextLoader);
                    ds = (javax.sql.DataSource) clazz.getConstructor().newInstance();
                } catch (Exception e) {
                    // context loader may not be correctly hooked up
                    // with parent, try without it.
                }
            }
            
            if (ds == null)
            {
                Class<?> clazz = Class.forName(classname);
                ds = (javax.sql.DataSource) clazz.getConstructor().newInstance();
            }
            
            for (Iterator i = beanProperties.keySet().iterator();
                i.hasNext(); )
            {
                String property = (String) i.next();
                Object value = beanProperties.get(property);
                
                setBeanProperty(ds, property, value);
            }

            if ( !BaseTestCase.isJ9Platform() && !BaseTestCase.isCVM() )
            {
                ds.setLoginTimeout( TestConfiguration.getCurrent().getLoginTimeout() );
            }
            
            return ds;
        } catch (Exception e) {
            BaseTestCase.printStackTrace( e );
            BaseTestCase.fail("unexpected error: " + e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * Set a bean property for a data source. This code can be used
     * on any data source type.
     * @param ds DataSource to have property set
     * @param property name of property.
     * @param value Value, type is derived from value's class.
     */
    public static void setBeanProperty(Object ds, String property, Object value)
    {
        String setterName = getSetterName(property);
        
        // Base the type of the setter method from the value's class.
        Class clazz = value.getClass();      
        if (Integer.class.equals(clazz))
            clazz = Integer.TYPE;
        else if (Boolean.class.equals(clazz))
            clazz = Boolean.TYPE;
        else if (Short.class.equals(clazz))
            clazz = Short.TYPE;

        try {
            Method setter = ds.getClass().getMethod(setterName,
                    new Class[] {clazz});
            setter.invoke(ds, new Object[] {value});
        } catch (Exception e) {
            Assert.fail(e.getMessage());
        }   
    }
    
    /**
     * Get a bean property for a data source. This code can be used
     * on any data source type.
     * @param ds DataSource to fetch property from
     * @param property name of property.
     */
    public static Object getBeanProperty(Object ds, String property)
        throws Exception
    {
        String getterName = getGetterName(property);

        Method getter = ds.getClass().getMethod(getterName,
                    new Class[0]);
        return getter.invoke(ds, new Object[0]);
    }
    
    /**
     * Clear a String Java bean property by setting it to null.
     * @param ds DataSource to have property cleared
     * @param property name of property.
     */
    public static void clearStringBeanProperty(Object ds, String property)
    {
        String setterName = getSetterName(property);
        try {
            Method setter = ds.getClass().getMethod(setterName,
                    new Class[] {String.class});
            setter.invoke(ds, new Object[] {null});
        } catch (Exception e) {
            Assert.fail(e.getMessage());
        }   
    }
    
    private static String getSetterName(String attribute) {
        return "set" + Character.toUpperCase(attribute.charAt(0))
                + attribute.substring(1);
    }
    private static String getGetterName(String attribute) {
        return "get" + Character.toUpperCase(attribute.charAt(0))
                + attribute.substring(1);
    }
    
    /**
     * Shutdown the database described by this data source.
     * The shutdownDatabase property is cleared by this method.
     */
    public static void shutdownDatabase(javax.sql.DataSource ds)
    {
        setBeanProperty(ds, "shutdownDatabase", "shutdown");
        try {
            ds.getConnection();
            Assert.fail("Database failed to shut down");
        } catch (SQLException e) {
             BaseJDBCTestCase.assertSQLState("Database shutdown", "08006", e);
        } finally {
            clearStringBeanProperty(ds, "shutdownDatabase");
        }
    }

    /**
     * Shutdown the engine described by this data source.
     * The shutdownDatabase property is cleared by this method.
     */
    public static void shutEngine(javax.sql.DataSource ds) throws SQLException {
        setBeanProperty(ds, "shutdownDatabase", "shutdown");
        JDBCDataSource.setBeanProperty(ds, "databaseName", "");
        try {
            ds.getConnection();
            Assert.fail("Engine failed to shut down");
        } catch (SQLException e) {
             BaseJDBCTestCase.assertSQLState("Engine shutdown", "XJ015", e);
        } finally {
            clearStringBeanProperty(ds, "shutdownDatabase");
        }
    }

}
