import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Logger;

import com.eurogiro.common.exception.BusinessException;
import com.eurogiro.common.exception.DBException;


public class AccessDB {
    private Connection connection = null;
    private Logger logger = Logger.getLogger(this.getClass().getPackage()
        .getName());

    /**
     * Constructor which internally gets a new connection.
     * 
     * @throws DBException thrown when any db error occurs.
     * @throws BusinessException thrown when any business error occurs while
     *                           getting connection.e.g. Error in decrypting
     *                           password used to connect to db. 
     */
    public AccessDB() throws DBException, BusinessException {
        if (null == connection) {
            try {
                connection = DatabaseConnectionManager.getInstance()
                        .getConnection();
            } catch (SQLException sqlEx) {
                logger.severe("SQLException while getting the connection");
                DBException dbEx = new DBException(sqlEx);
                dbEx.setMessage("Error getting db connection");
                dbEx.setErrorCode("DBERROR-51");
                throw dbEx;
            }
        }
    }

    /**
     * This method returns the connection.
     *
     * @return Returns the connection.
     */
    public Connection getConnection() {
        return connection;
    }

    /**
     * This method sets the conneciton.
     *
     * @param strConnection The connection to set.
     */
    public void setConnection(Connection strConnection) {
        connection = strConnection;
    }

    /**
     * Commit the existing Transaction.
     *
     * @throws DBException thrown when error in commiting a transaction.
     */
    public void commit() throws DBException {
        try {
            // Try commit the transaction 
            connection.commit();
        } catch (SQLException sqlException) {
            DBException dbEx = new DBException(sqlException);
            dbEx.setMessage("Error while database commit");
            dbEx.setErrorCode("DBERROR-56");
            throw dbEx;
        }
    }

    /**
     * This method sets the auto commit flag to false.
     *
     * @param bIsAutoCommit boolean true;ON false;OFF
     * @throws DBException is thrown when error occurs while setting auto
     *                     commit flag.
     */
    public void setAutoCommit(boolean bIsAutoCommit) throws DBException {
        try {
            connection.setAutoCommit(bIsAutoCommit);
        } catch (SQLException sqlException) {
            logger.severe("SQLException while setting auto commit");
            DBException dbEx = new DBException(sqlException);
            dbEx.setMessage("Error while setting auto commit flag to: "
                    + bIsAutoCommit);
            dbEx.setErrorCode("DBERROR-58");
            throw dbEx;
        }
        return;
    }

    /**
     * rollback - rollback the current transaction
     *
     * @throws DBException thrown when error in rollbacking a transaction.
     */
    public void rollback() throws DBException {
        try {
            connection.rollback();
        } catch (SQLException sqlException) {
            logger.severe("SQLException while performing rollback");
            DBException dbEx = new DBException(sqlException);
            dbEx.setMessage("Error while database rollback");
            dbEx.setErrorCode("DBERROR-57");
            throw dbEx;
        }
        return;
    }

    /**
     * Connection close method
     *
     * @throws DBException thrown when error in closing connection.
     */
    public void close() throws DBException {
        // close Method for closing the connection
        try {
            if (connection != null && !(connection.isClosed())) {
                // Close the connection
                if (!connection.getAutoCommit()) {
                    connection.rollback();
                }
                connection.close();
            }
        } catch (SQLException sqlEx) {
            DBException dbEx = new DBException(sqlEx);
            throw dbEx;
        }
    }
    
    /**
     * This method sets the Isolation level of the transaction.
     * 
     * @param nIsoLevel Isolation level
     * @throws DBException 
     */
    public void setIsolationlevel(int nIsoLevel) throws DBException {
        if (connection != null) {
            try {
                logger.info("Setting tx level to :  " + nIsoLevel);
                connection.setTransactionIsolation(nIsoLevel);
            } catch (Exception ex) {
                DBException dbEx = new DBException();
                dbEx.setErrorCode("DBERROR-59");
                dbEx.setMessage("Error setting tx isolation level");
                throw dbEx;
            }
        }
    }
}