/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 *     02/08/2012-2.4 Guy Pelletier 
 *       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
 *     06/20/2012-2.5 Guy Pelletier 
 *       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
 *     07/13/2012-2.5 Guy Pelletier 
 *       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
 *     08/24/2012-2.5 Guy Pelletier 
 *       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
 *     09/27/2012-2.5 Guy Pelletier
 *       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
 ******************************************************************************/  
package org.eclipse.persistence.queries;

import java.util.*;

import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.sessions.DatabaseRecord;

/**
 * <p><b>Purpose</b>:
 * Concrete class to perform read using raw SQL and the SQLResultSetMapping.
 * <p>
 * <p><b>Responsibilities</b>:
 * Execute a selecting raw SQL string.
 * Returns a List of results.  Each item in the list will be another list
 * consisting of the expected populated return types in the order they were
 * specified in the SQLResultSetMapping
 *
 * @see SQLResultSetMapping
 * @author Gordon Yorke
 * @since TopLink Java Essentials
 */
public class ResultSetMappingQuery extends ObjectBuildingQuery {
    protected boolean isExecuteCall;
    protected boolean returnNameValuePairs = false;
    protected Vector resultRows;
    
    protected List<String> resultSetMappingNames = new ArrayList<String>();
    protected List<SQLResultSetMapping> resultSetMappings = new ArrayList<SQLResultSetMapping>();
    
    /**
     * PUBLIC:
     * Initialize the state of the query.
     */
    public ResultSetMappingQuery() {
        super();
   }

    /**
     * PUBLIC:
     * Initialize the query to use the specified call.
     */
    public ResultSetMappingQuery(Call call) {
        this();
        setCall(call);
    }

    /**
     * PUBLIC:
     * Initialize the query to use the specified call and SQLResultSetMapping
     */
    public ResultSetMappingQuery(Call call, String sqlResultSetMappingName) {
        this();
        setCall(call);
        this.resultSetMappingNames.add(sqlResultSetMappingName);
    }

    /**
     * PUBLIC:
     * This will be the SQLResultSetMapping that is used by this query to process
     * the database results
     */
    public void addSQLResultSetMapping(SQLResultSetMapping resultSetMapping){
        this.resultSetMappings.add(resultSetMapping);
        this.resultSetMappingNames.add(resultSetMapping.getName());
    }
    
    /**
     * PUBLIC:
     * Add a SQLResultSetMapping that is used by this query to process the 
     * database results.
     */
    public void addSQLResultSetMappingName(String name){
        if (name == null) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_sqlresultsetmapping_in_query"));
        }
        
        this.resultSetMappingNames.add(name);
    }
    
    /**
     * INTERNAL:
     * <P> This method is called by the object builder when building an original.
     * It will cause the original to be cached in the query results if the query
     * is set to do so.
     */
    @Override
    public void cacheResult(Object unwrappedOriginal) {
        Object cachableObject = unwrappedOriginal;
        if (shouldUseWrapperPolicy()){
            cachableObject = getSession().wrapObject(unwrappedOriginal);
        }
        setTemporaryCachedQueryResults(cachableObject);
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this ResultSetMapping to actual class-based
     * settings. This method is used when converting a project that has been built
     * with class names to a project with classes.
     */
    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        for (SQLResultSetMapping mapping : this.resultSetMappings) {
            mapping.convertClassNamesToClasses(classLoader);
        }
    }

    /**
     * Indicates whether or not to return populated DatabaseRecord(s)
     * as opposed to raw data when an SQLResultSetMapping is not set.
     */
    public boolean shouldReturnNameValuePairs() {
        return returnNameValuePairs;
    }

    /**
     * Set the flag that indicates whether or not to return populated
     * DatabaseRecord(s) as opposed to raw data when an
     * SQLResultSetMapping is not set.
     */
    public void setShouldReturnNameValuePairs(boolean returnNameValuePairs) {
        this.returnNameValuePairs = returnNameValuePairs;
    }

    /**
     * PUBLIC:
     * This will be the SQLResultSetMapping that is used by this query to process
     * the database results
     */
    public void setSQLResultSetMapping(SQLResultSetMapping resultSetMapping) {
        addSQLResultSetMapping(resultSetMapping);
    }
    
    /**
     * PUBLIC:
     * This will be the SQLResultSetMappings that are used by this query to 
     * process the database results
     */
    public void setSQLResultSetMappings(List<SQLResultSetMapping> resultSetMappings) {
        this.resultSetMappings = resultSetMappings;
    }

    /**
     * PUBLIC:
     * This will be the SQLResultSetMapping that is used by this query to process
     * the database results
     */
    public void setSQLResultSetMappingName(String name) {
        addSQLResultSetMappingName(name);
    }
    
    /**
     * PUBLIC:
     * This will be the SQLResult
     * @param names
     */
    public void setSQLResultSetMappingNames(List<String> names) {
        if (names.isEmpty()) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_sqlresultsetmapping_in_query"));
        }
        
        this.resultSetMappingNames = names;
    }
    
    /**
     * INTERNAL:
     * This method is used to build the results. Interpreting the 
     * SQLResultSetMapping(s).
     */
    public List buildObjectsFromRecords(List databaseRecords){
        if (getSQLResultSetMappings().size() > 1) {
            int numberOfRecords = databaseRecords.size();
            List results = new ArrayList(numberOfRecords);
        
            for (int recordIndex = 0; recordIndex < numberOfRecords; recordIndex++) {
                Object records = databaseRecords.get(recordIndex);
                
                if (records instanceof Map) {
                    // We have a map keyed on named ref_cursors
                    Map recordsMap = (Map) records;
                    
                    for (Object cursor : recordsMap.keySet()) {
                        results.add(buildObjectsFromRecords((List) recordsMap.get(cursor), getSQLResultSetMappings().get(recordIndex)));
                        recordIndex++;
                    }
                } else {
                    // Regular list of records, iterate through them.
                    results.add(buildObjectsFromRecords((List) records, getSQLResultSetMappings().get(recordIndex)));
                }
            }
        
            return results;
        } else {
            return buildObjectsFromRecords(databaseRecords, getSQLResultSetMapping());
        }
    }
    
    /**
     * INTERNAL:
     * This method is used to build the results with the SQLResultSetMapping
     * at the given index.
     */
    public List buildObjectsFromRecords(List databaseRecords, int index){
        if (getSQLResultSetMappings().isEmpty()) {
            return buildObjectsFromRecords(databaseRecords, null);
        } else {
            return buildObjectsFromRecords(databaseRecords, getSQLResultSetMappings().get(index));
        }
    }
    
    /**
     * INTERNAL:
     * This method is used to build the results. Interpreting the SQLResultSetMapping.
     */
    protected List buildObjectsFromRecords(List databaseRecords, SQLResultSetMapping mapping) {
        int numberOfRecords = databaseRecords.size();
        List results = new ArrayList(numberOfRecords);
        
        if (mapping == null) {
            if (shouldReturnNameValuePairs()) {
                return databaseRecords;
            }
            for (Iterator iterator = databaseRecords.iterator(); iterator.hasNext();) {
                DatabaseRecord record = (DatabaseRecord)iterator.next();                
                results.add(record.values().toArray());
            }
        } else {
            for (Iterator iterator = databaseRecords.iterator(); iterator.hasNext();) {
                if (mapping.getResults().size() > 1) {
                    Object[] resultElement = new Object[mapping.getResults().size()];
                    DatabaseRecord record = (DatabaseRecord)iterator.next();
                    for (int i = 0; i < mapping.getResults().size(); i++) {
                        resultElement[i] = ((SQLResult)mapping.getResults().get(i)).getValueFromRecord(record, this);
                    }
                    results.add(resultElement);
                } else if (mapping.getResults().size() == 1) {
                    DatabaseRecord record = (DatabaseRecord)iterator.next();
                    results.add(((SQLResult)mapping.getResults().get(0)).getValueFromRecord(record, this));
                } else {
                    return results;
                }
            }
        }
        
        return results;
    }

    /**
     * INTERNAL:
     * Executes the prepared query on the datastore.
     */
    @Override
    public Object executeDatabaseQuery() throws DatabaseException {
        if (getSession().isUnitOfWork()) {
            UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl)getSession();

            // Note if a nested unit of work this will recursively start a
            // transaction early on the parent also.
            if (isLockQuery()) {
                if ((!unitOfWork.getCommitManager().isActive()) && (!unitOfWork.wasTransactionBegunPrematurely())) {
                    unitOfWork.beginTransaction();
                    unitOfWork.setWasTransactionBegunPrematurely(true);
                }
            }
            if (unitOfWork.isNestedUnitOfWork()) {
                // execute in parent UOW then register normally here.
                UnitOfWorkImpl nestedUnitOfWork = (UnitOfWorkImpl)getSession();
                setSession(nestedUnitOfWork.getParent());
                Object result = executeDatabaseQuery();
                setSession(nestedUnitOfWork);
                Object clone = registerIndividualResult(result, null, unitOfWork, null, null);

                if (shouldUseWrapperPolicy()) {
                    clone = getDescriptor().getObjectBuilder().wrapObject(clone, unitOfWork);
                }
                return clone;
            }
        }
        session.validateQuery(this);// this will update the query with any settings

        if (getQueryId() == 0) {
            setQueryId(getSession().getNextQueryId());
        }

        if (getCall().isExecuteUpdate()) {
            DatabaseCall call = ((StoredProcedureCall) getQueryMechanism().execute());
            setExecutionTime(System.currentTimeMillis());
            return call;
        } else {
            Vector rows = getQueryMechanism().executeSelect();
            setExecutionTime(System.currentTimeMillis());
            // If using 1-m joins, must set all rows.
            return buildObjectsFromRecords(rows);
        }
    }
    
    /**
     * PUBLIC:
     * Return true if there are results set mappings associated with this query.
     */
    public boolean hasResultSetMappings() {
        return ! getSQLResultSetMappings().isEmpty();
    }
    
    /**
     * PUBLIC: Return true if this is a result set mapping query.
     */
    public boolean isResultSetMappingQuery() {
        return true;
    }
    
    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    protected void prepare() {
        if ((!shouldMaintainCache()) && shouldRefreshIdentityMapResult()) {
            throw QueryException.refreshNotPossibleWithoutCache(this);
        }

        getQueryMechanism().prepare();

        if (isExecuteCall) {
            getQueryMechanism().prepareExecute();
        } else {
            getQueryMechanism().prepareExecuteSelect();
        }
    }

    /**
     * PUBLIC:
     * This will be the SQLResultSetMapping that is used by this query to process
     * the database results
     */
    public SQLResultSetMapping getSQLResultSetMapping() {
        if (resultSetMappings.isEmpty()) {
            if (resultSetMappingNames.isEmpty()) {
                return null;
            } else {
                return getSession().getProject().getSQLResultSetMapping(resultSetMappingNames.get(0));
            }
        }
        
        return resultSetMappings.get(0);
    }
    
    /**
     * PUBLIC:
     * This will be the SQLResultSetMapping that is used by this query to process
     * the database results
     */
    public List<SQLResultSetMapping> getSQLResultSetMappings() {
        if (this.resultSetMappings.isEmpty()) {
            ArrayList<SQLResultSetMapping> list = new ArrayList<SQLResultSetMapping>();
            for (String resultSetMappingName : this.resultSetMappingNames) {
                list.add(getSession().getProject().getSQLResultSetMapping(resultSetMappingName));
            }
            
            return list;
        } else {
            return resultSetMappings;
        }
    }
    
    /**
     * PUBLIC:
     * Return the result set mapping name.
     */
    public String getSQLResultSetMappingName() {
        return this.resultSetMappingNames.get(0);
    }
    
    /**
     * PUBLIC:
     * Return the result set mapping name.
     */
    public List<String> getSQLResultSetMappingNames() {
        return this.resultSetMappingNames;
    }
    
    /**
     * PUBLIC:
     * Set to true if you the actual jdbc result set returned from query
     * execution. This will unprepare the query in case it was executed
     * previously for a getResultList() call instead (or vice versa)
     */
    public void setIsExecuteCall(boolean isExecuteCall) {
        this.isExecuteCall = isExecuteCall;
        
        // Force the query to prepare.
        setIsPrepared(false);
    }
}
