/*******************************************************************************
 * 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
 ******************************************************************************/  
package org.eclipse.persistence.queries;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.mappings.OneToOneMapping;
import org.eclipse.persistence.sessions.DatabaseRecord;

/**
 * <p><b>Purpose</b>:
 * Concrete class to represent the EntityResult structure as defined by
 * the EJB 3.0 Persistence specification.  This class is a subcomponent of the 
 * SQLResultSetMapping
 * 
 * @see SQLResultSetMapping
 * @author Gordon Yorke
 * @since TopLink Java Essentials
 */
public class EntityResult extends SQLResult {
    /** Stores the class name of result  */
    protected String entityClassName;
    protected transient Class entityClass;
    
    /** Stores the list of FieldResult */
    protected Map fieldResults;
    
    /** Stores the column that will contain the value to determine the correct subclass
     * to create if applicable.
     */
    protected DatabaseField discriminatorColumn;
    
    public EntityResult(Class entityClass){
        this.entityClass = entityClass;
        if (this.entityClass == null){
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_value_for_entity_result"));
        }
        this.entityClassName = entityClass.getName();
    }
    
    public EntityResult(String entityClassName){
        this.entityClassName = entityClassName;
        if (this.entityClassName == null){
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_value_for_entity_result"));
        }
    }
    
    public void addFieldResult(FieldResult fieldResult){
        if (fieldResult == null || fieldResult.getAttributeName() == null){
            return;
        }
        FieldResult existingFieldResult = (FieldResult)getFieldResults().get(fieldResult.getAttributeName());
        if (existingFieldResult==null){
            getFieldResults().put(fieldResult.getAttributeName(), fieldResult);
        }else{
            existingFieldResult.add(fieldResult);
        }
    }
    
    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this query 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.
     * @param classLoader 
     */
    public void convertClassNamesToClasses(ClassLoader classLoader){
        super.convertClassNamesToClasses(classLoader);
        Class entityClass = null;
        try{
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    entityClass = (Class)AccessController.doPrivileged(new PrivilegedClassForName(entityClassName, true, classLoader));
                } catch (PrivilegedActionException exception) {
                    throw ValidationException.classNotFoundWhileConvertingClassNames(entityClassName, exception.getException());
                }
            } else {
                entityClass = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(entityClassName, true, classLoader);
            }
        } catch (ClassNotFoundException exc){
            throw ValidationException.classNotFoundWhileConvertingClassNames(entityClassName, exc);
        }
        this.entityClass = entityClass;
    };   

    /**
     * Accessor for the internally stored list of FieldResult.  Calling this
     * method will result in a collection being created to store the FieldResult
     */
    public Map getFieldResults(){
        if (this.fieldResults == null){
            this.fieldResults = new HashMap();
        }
        return this.fieldResults;
    }
    
    /**
     * Returns the column name for the column that will store the value used to
     * determine the subclass type if applicable.
     */
    public DatabaseField getDiscriminatorColumn(){
        return this.discriminatorColumn;
    }

    /**
     * Sets the column name for the column that will store the value used to
     * determine the subclass type if applicable.
     */
    public void setDiscriminatorColumn(String column){
        if (column == null){
            return;
        }
        this.discriminatorColumn = new DatabaseField(column);
    }
    
    public void setDiscriminatorColumn(DatabaseField column){
        if (column == null){
            return;
        }
        this.discriminatorColumn = column;
    }

    /**
     * INTERNAL:
     * This method is a convenience method for extracting values from Results
     */
    public Object getValueFromRecord(DatabaseRecord record, ResultSetMappingQuery query){
        // From the row data build result entity.
        // To do this let's collect the column based data for this entity from
        // the results and call build object with this new row.
        ClassDescriptor descriptor = query.getSession().getDescriptor(this.entityClass);
        DatabaseRecord entityRecord = new DatabaseRecord(descriptor.getFields().size());
        if (descriptor.hasInheritance()) {
            Object value = null;
            if (this.discriminatorColumn == null) {
                value = record.get(descriptor.getInheritancePolicy().getClassIndicatorField());
            } else {
                value = record.getIndicatingNoEntry(this.discriminatorColumn);
                if (value == AbstractRecord.noEntry){
                    throw QueryException.discriminatorColumnNotSelected(this.discriminatorColumn.getName(), getSQLResultMapping().getName());
                }
            }            
            entityRecord.put(descriptor.getInheritancePolicy().getClassIndicatorField(), value);
            
            // if multiple types may have been read get the correct descriptor.
            if ( descriptor.getInheritancePolicy().shouldReadSubclasses()) {
                Class classValue = descriptor.getInheritancePolicy().classFromRow(entityRecord, query.getSession());
                descriptor = query.getSession().getDescriptor(classValue);
            }
        }
        for (Iterator mappings = descriptor.getMappings().iterator(); mappings.hasNext();) {
            DatabaseMapping mapping = (DatabaseMapping)mappings.next();
            FieldResult fieldResult = (FieldResult)this.getFieldResults().get(mapping.getAttributeName());
            if (fieldResult != null){
                if (mapping.getFields().size() == 1 ) {
                    entityRecord.put(mapping.getFields().firstElement(), record.get(fieldResult.getColumn()));
                } else if (mapping.getFields().size() >1){
                    getValueFromRecordForMapping(entityRecord,mapping,fieldResult,record);
                }
            } else {
                for (Iterator fields = mapping.getFields().iterator(); fields.hasNext();) {
                    DatabaseField field = (DatabaseField)fields.next();
                    entityRecord.put(field, record.get(field));
                }
            }
        }
        query.setReferenceClass(this.entityClass);
        query.setDescriptor(descriptor);
        //TODO : support prefetchedCacheKeys in ResultSetMappingQuery
        return descriptor.getObjectBuilder().buildObject(query, entityRecord, null);
    }

    public boolean isEntityResult(){
        return true;
    }
    
    /**
     * INTERNAL:
     *   This method is for processing all FieldResults for a mapping.  Adds DatabaseFields to the passed in entityRecord
     */
    public void getValueFromRecordForMapping(DatabaseRecord entityRecord,DatabaseMapping mapping, FieldResult fieldResult, DatabaseRecord databaseRecord){
        ClassDescriptor currentDescriptor = mapping.getReferenceDescriptor();
        /** check if this FieldResult contains any other FieldResults, process it if it doesn't */
        if (fieldResult.getFieldResults()==null){
            DatabaseField dbfield = processValueFromRecordForMapping(currentDescriptor,fieldResult.getMultipleFieldIdentifiers(),1);
            /** If it is a 1:1 mapping we need to do the target to source field conversion.  If it is an aggregate, it is fine as it is*/
            if (mapping.isOneToOneMapping()){
                dbfield = (((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(dbfield));
            }
            entityRecord.put(dbfield, databaseRecord.get(fieldResult.getColumn()));
            return;
        }
        /** This processes each FieldResult stored in the collection of FieldResults individually */
        Iterator fieldResults = fieldResult.getFieldResults().iterator();
        while (fieldResults.hasNext()){
            FieldResult tempFieldResult = ((FieldResult)fieldResults.next());
            DatabaseField dbfield = processValueFromRecordForMapping(currentDescriptor,tempFieldResult.getMultipleFieldIdentifiers(),1);
             if (mapping.isOneToOneMapping()){
                dbfield = (((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(dbfield));
            }
            entityRecord.put(dbfield, databaseRecord.get(tempFieldResult.getColumn()));
        }
    }
    
    /**
     * INTERNAL:
     *   This method is for processing a single FieldResult, returning the DatabaseField it refers to.
     */
    public DatabaseField processValueFromRecordForMapping(ClassDescriptor descriptor, String[] attributeNames, int currentLoc){
        DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForAttributeName(attributeNames[currentLoc]);
        if (mapping==null){throw QueryException.mappingForFieldResultNotFound(attributeNames,currentLoc);}
        currentLoc++;
        if (attributeNames.length!=currentLoc){
            ClassDescriptor currentDescriptor = mapping.getReferenceDescriptor();
            DatabaseField df= processValueFromRecordForMapping(currentDescriptor, attributeNames, currentLoc);
            if (mapping.isOneToOneMapping()){
                return (((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(df));
            }
            return df;
        }else{
            //this is it.. return this mapping's field
            return mapping.getFields().firstElement();
        }
    }
    
}
