/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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.queplix.core.modules.services.utils.db;

import com.queplix.core.error.GenericSystemException;
import com.queplix.core.modules.services.jxb.Script;
import com.queplix.core.modules.services.utils.ScriptDAO;
import com.queplix.core.utils.dao.AbstractDAO;
import com.queplix.core.utils.sql.SqlWrapper;
import com.queplix.core.utils.sql.SqlWrapperFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

/**
 * Project-specific implementation of the ScriptDAO
 *
 * @author [ALB] Baranov Andrey
 * @version $Revision: 1.1.1.1 $ $Date: 2005/09/12 15:31:01 $
 */

public class ScriptDAOImpl
        extends AbstractDAO implements ScriptDAO {

    // ===================================================== Fields

    /**
     * SQL wrapper implementation reference.
     */
    protected SqlWrapper sqlWrapper = SqlWrapperFactory.getSqlWrapper();

    // ===================================================== Overridden methods

    /*
     * (non-javadoc)
     *
     * @see ScriptDAO#deleteScriptVO
     */

    public int deleteScriptVO(Script script) {
        /** @todo [ALB] implement it */
        throw new UnsupportedOperationException();
    }

    /*
     * (non-javadoc)
     *
     * @see ScriptDAO#updateScriptVO
     */
    public int updateScriptVO(Script script) {
        /** @todo [ALB] implement it */
        throw new UnsupportedOperationException();
    }

    /*
     * (non-javadoc)
     *
     * @see ScriptDAO#loadScriptVO
     */
    public Script loadScriptVO(int scriptId) {

        if(getLogger().isDebugEnabled()) {
            DEBUG("Try to get data for " + scriptId + " script");
        }

        Script script = null;
        Connection con = null;
        PreparedStatement ps = null;

        try {
            // Open connection.
            con = sqlWrapper.doConnection();

            // Execute main SQL query.
            String sql = DBRealmManager.getSql("select_script");
            ps = sqlWrapper.doPreparedStatement(con, sql);
            ps.setInt(1, scriptId);

            // Read main data.
            ResultSet rs = sqlWrapper.executeQuery(ps);
            if(!rs.next()) {
                return null;
            }
            script = createScript(rs);
            rs.close();
            ps.close();

        } catch (SQLException ex) {
            throw new GenericSystemException(
                    "SQL exception: " + ex.getMessage(), ex);

        } finally {
            sqlWrapper.closeConnection(con, ps);
        }

        if(getLogger().isDebugEnabled()) {
            DEBUG("Got script VO for " + scriptId + " : " + script);
        }

        return script;
    }

    /*
     * (non-javadoc)
     *
     * @see ScriptDAO#loadScriptVO
     */
    public Script loadScriptVO(String scriptName) {

        if(getLogger().isDebugEnabled()) {
            DEBUG("Try to get data for '" + scriptName + "' script");
        }

        Script script = null;
        Connection con = null;
        PreparedStatement ps = null;

        try {
            // Open connection.
            con = sqlWrapper.doConnection();

            // Execute main SQL query.
            String sql = DBRealmManager.getSql("select_script_by_name");
            ps = sqlWrapper.doPreparedStatement(con, sql);
            ps.setString(1, scriptName);

            // Read main data.
            ResultSet rs = sqlWrapper.executeQuery(ps);
            if(!rs.next()) {
                return null;
            }
            script = createScript(rs);
            rs.close();
            ps.close();

        } catch (SQLException ex) {
            throw new GenericSystemException(
                    "SQL exception: " + ex.getMessage(), ex);

        } finally {
            sqlWrapper.closeConnection(con, ps);
        }

        if(getLogger().isDebugEnabled()) {
            DEBUG("Got script VO for '" + scriptName + "' : " + script);
        }

        return script;
    }

    /*
     * (non-javadoc)
     *
     * @see ScriptDAO#loadAllScriptVO
     */
    public Collection loadAllScriptVO() {

        Connection con = null;
        PreparedStatement ps = null;

        Collection scriptList = new ArrayList();

        try {
            con = sqlWrapper.doConnection();
            ps = sqlWrapper.doPreparedStatement(con, DBRealmManager.getSql(
                    "select_all_script"));
            ResultSet rs = sqlWrapper.executeQuery(ps);
            while(rs.next()) {
                Script script = createScript(rs);
                scriptList.add(script);
            }

        } catch (SQLException ex) {
            throw new GenericSystemException(
                    "SQL exception: " + ex.getMessage(), ex);

        } finally {
            sqlWrapper.closeConnection(con, ps);
        }

        return scriptList;
    }

    // ===================================================== Protected methods

    //
    // Creates Script from ResultSet
    // [ALB] without script parameters
    //

    protected Script createScript(ResultSet rs)
            throws SQLException {

        // Read mandatory data.
        int i = 1;
        int scriptID = rs.getInt(i++);
        String name = rs.getString(i++);
        String className = rs.getString(i++);
        String description = rs.getString(i++);

        // create Script object
        Script script = new Script();
        script.setId(new Integer(scriptID));
        script.setName(name);
        script.setClassName(className);
        script.setDescription(description);

        // get list of script parameters
        /* We don't use parameters yet
        PreparedStatement ps = null;

        try {
            ps = sqlWrapper.doPreparedStatement( rs.getStatement().getConnection(), DBRealmManager.getSql( "select_script_parameters" ) );
            ps.setInt( 1, scriptID );
            ResultSet rs2 = sqlWrapper.executeQuery( ps );
            while( rs2.next() ) {
                i = 1;
                String paramName = rs2.getString( i++ );
                String paramValue = rs2.getString( i++ );
                Integer paramRequired = sqlWrapper.getIntParser().getValue( rs2, i++ );
                Integer paramType = sqlWrapper.getIntParser().getValue( rs2, i++ );

                Param param = new Param();
                param.setName( paramName );
                param.setValue( paramValue );
                if( paramRequired != null ) {
                    param.setRequired( new Boolean( paramRequired.intValue() == 1 ) );
                } else {
                    param.setRequired( Boolean.FALSE );
                }

                // set param type
                if( paramType != null ) {
                    int param_type = paramType.intValue();
                    switch( param_type ) {
                        case ParamTypeSType.INT_TYPE:
                            param.setType( ParamTypeSType.INT );
                            break;
                        case ParamTypeSType.LONG_TYPE:
                            param.setType( ParamTypeSType.LONG );
                            break;
                        case ParamTypeSType.FLOAT_TYPE:
                            param.setType( ParamTypeSType.FLOAT );
                            break;
                        case ParamTypeSType.STRING_TYPE:
                            param.setType( ParamTypeSType.STRING );
                            break;
                        default:
                            throw new IllegalStateException( "Unsupported script param type: " + param_type );
                    }
                }

                // add Param object into Script object
                script.addParam( param );
            }

        } catch( SQLException ex ) {
            throw new GenericSystemException( "SQL exception: " + ex.getMessage(), ex );

        } finally {
            sqlWrapper.closeConnection( ps );
        }
*/
        return script;
    }
}
