/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  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.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.business;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.business.startup.StartupException;
import org.apache.roller.weblogger.config.WebloggerConfig;


/**
 * Encapsulates Roller database configuration via JDBC properties or JNDI.
 * 
 * <p>To keep the logs from filling up with DB connection errors, will only 
 * attempt to connect once.</p>
 * 
 * <p>Keeps startup exception and log so we can present useful debugging
 * information to whoever is installing Roller.</p>
 * 
 * 
 * <p>Reads configuration properties from WebloggerConfig:</p>
 * <pre>
 * # Specify database configuration type of 'jndi' or 'jdbc'
 * database.configurationType=jndi
 * 
 * # For database configuration type 'jndi',this will be used
 * database.jndi.name=jdbc/rollerdb
 * 
 * # For database configuration type of 'jdbc', you MUST override these
 * database.jdbc.driverClass=
 * database.jdbc.connectionURL=
 * database.jdbc.username=
 * database.jdbc.password=
 * </pre>
 */
public class DatabaseProvider  {
    
    private static Log log = LogFactory.getLog(DatabaseProvider.class);

    public enum ConfigurationType {JNDI_NAME, JDBC_PROPERTIES}
    private ConfigurationType type = ConfigurationType.JNDI_NAME;
    private List<String> startupLog = new ArrayList<String>();
    
    private DataSource dataSource = null;    
    private String jndiName = null; 
    
    private String jdbcDriverClass = null;
    private String jdbcConnectionURL = null;
    private String jdbcPassword = null;
    private String jdbcUsername = null;
    private Properties props = null;
    
    
    /**
     * Reads configuraiton, loads driver or locates data-source and attempts
     * to get test connecton so that we can fail early.
     */ 
    public DatabaseProvider() throws StartupException {
        
        String connectionTypeString = 
                WebloggerConfig.getProperty("database.configurationType"); 
        if ("jdbc".equals(connectionTypeString)) {
            type = ConfigurationType.JDBC_PROPERTIES;
        }
        jndiName =          WebloggerConfig.getProperty("database.jndi.name");
        jdbcDriverClass =   WebloggerConfig.getProperty("database.jdbc.driverClass");
        jdbcConnectionURL = WebloggerConfig.getProperty("database.jdbc.connectionURL");
        jdbcUsername =      WebloggerConfig.getProperty("database.jdbc.username");
        jdbcPassword =      WebloggerConfig.getProperty("database.jdbc.password");
        
        successMessage("SUCCESS: Got parameters. Using configuration type " + type);

        // If we're doing JDBC then attempt to load JDBC driver class
        if (getType() == ConfigurationType.JDBC_PROPERTIES) {
            successMessage("-- Using JDBC driver class: "   + jdbcDriverClass);
            successMessage("-- Using JDBC connection URL: " + jdbcConnectionURL);
            successMessage("-- Using JDBC username: "       + jdbcUsername);
            successMessage("-- Using JDBC password: [hidden]");
            try {
                Class.forName(getJdbcDriverClass());
            } catch (ClassNotFoundException ex) {
                String errorMsg = 
                     "ERROR: cannot load JDBC driver class [" + getJdbcDriverClass()+ "]. "
                    +"Likely problem: JDBC driver jar missing from server classpath.";
                errorMessage(errorMsg);
                throw new StartupException(errorMsg, ex, startupLog);
            }
            successMessage("SUCCESS: loaded JDBC driver class [" +getJdbcDriverClass()+ "]");
            
            if (getJdbcUsername() != null || getJdbcPassword() != null) {
                props = new Properties();
                if (getJdbcUsername() != null) {
                    props.put("user", getJdbcUsername());
                }
                if (getJdbcPassword() != null) {
                    props.put("password", getJdbcPassword());
                }
            }
            
        // Else attempt to locate JNDI datasource
        } else { 
            String name = getFullJndiName();
            successMessage("-- Using JNDI datasource name: " + name);
            try {
                InitialContext ic = new InitialContext();
                dataSource = (DataSource)ic.lookup(name);
            } catch (NamingException ex) {
                String errorMsg = 
                    "ERROR: cannot locate JNDI DataSource [" +name+ "]. "
                   +"Likely problem: no DataSource or datasource is misconfigured.";
                errorMessage(errorMsg);
                throw new StartupException(errorMsg, ex, startupLog);
            }            
            successMessage("SUCCESS: located JNDI DataSource [" +name+ "]");
        }
        
        // So far so good. Now, can we get a connection?
        try { 
            Connection testcon = getConnection();
            testcon.close();
        } catch (Exception e) {
            String errorMsg = 
                "ERROR: unable to obtain database connection. "
               +"Likely problem: bad connection parameters or database unavailable.";
            errorMessage(errorMsg);
            throw new StartupException(errorMsg, e, startupLog);
        }
    }
    
    
    private void successMessage(String msg) {
        startupLog.add(msg);
        log.info(msg);
    }
    
    private void errorMessage(String msg) {
        startupLog.add(msg);
        log.error(msg);
    }
    

    /** 
     * List of success and error messages when class was first instantiated.
     **/
    public List<String> getStartupLog() {
        return startupLog;
    }

    /**
     * Get database connection from data-source or driver manager, depending 
     * on which is configured.
     */
    public Connection getConnection() throws SQLException {
        if (getType() == ConfigurationType.JDBC_PROPERTIES) {
            return DriverManager.getConnection(getJdbcConnectionURL(), props);
        } else {
            return dataSource.getConnection();
        }
    } 

    public ConfigurationType getType() {
        return type;
    }

    public String getJndiName() {
        return jndiName;
    }

    public String getJdbcDriverClass() {
        return jdbcDriverClass;
    }

    public String getJdbcConnectionURL() {
        return jdbcConnectionURL;
    }

    public String getJdbcPassword() {
        return jdbcPassword;
    }

    public String getJdbcUsername() {
        return jdbcUsername;
    }
    
    public String getFullJndiName() {
        if (null != jndiName && jndiName.startsWith("java:")) {
            return jndiName;
        }
        return "java:comp/env/" + jndiName;
    }

}
