/*******************************************************************************
 * 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
 *     11/10/2011-2.4 Guy Pelletier 
 *       - 357474: Address primaryKey option from tenant discriminator column
 ******************************************************************************/  
package org.eclipse.persistence.queries;

import java.io.*;
import java.util.*;
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.expressions.MapEntryExpression;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.identitymaps.CacheId;
import org.eclipse.persistence.internal.queries.*;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.mappings.foundation.AbstractColumnMapping;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.Session;

/**
 * <b>Purpose</b>: A single row (type) result for a ReportQuery<p>
 *
 * <b>Description</b>: Represents a single row of attribute values (converted using mapping) for
 * a ReportQuery. The attributes can be from various objects.
 *
 * <b>Responsibilities</b>:<ul>
 * <li> Converted field values into object attribute values.
 * <li> Provide access to values by index or item name
 * </ul>
 *
 * @author Doug Clarke
 * @since TOPLink/Java 2.0
 */
public class ReportQueryResult implements Serializable, Map {

    /** Item names to lookup result values */
    protected List<String> names;

    /** Actual converted attribute values */
    protected List<Object> results;

    /** Id value if the retrievPKs flag was set on the ReportQuery. These can be used to get the actual object */
    protected Object primaryKey;
    
    /** If an objectLevel distinct is used then generate unique key for this result */
    // GF_ISSUE_395
    protected StringBuffer key;

    /**
     * INTERNAL:
     * Used to create test results
     */
    public ReportQueryResult(List<Object> results, Object primaryKeyValues) {
        this.results = results;
        this.primaryKey = primaryKeyValues;
    }

    public ReportQueryResult(ReportQuery query, AbstractRecord row, Vector toManyResults) {
        super();
        this.names = query.getNames();
        buildResult(query, row, toManyResults);
    }

    /**
     * INTERNAL:
     * Create an array of attribute values (converted from raw field values using the mapping).
     */
    protected void buildResult(ReportQuery query, AbstractRecord row, Vector toManyData) {
        // GF_ISSUE_395
        if (query.shouldDistinctBeUsed() && (query.shouldFilterDuplicates())) {
            this.key = new StringBuffer();
        }
        List items = query.getItems();
        int itemSize = items.size();
        List results = new ArrayList(itemSize);

        if (query.shouldRetrievePrimaryKeys()) {
            setId(query.getDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(row, query.getSession()));
            // For bug 3115576 this is only used for EXISTS sub-selects so no result is needed.
        }
        for (int index = 0; index < itemSize; index++) {
            ReportItem item = (ReportItem)items.get(index);
            if (item.isConstructorItem()) {
                // For constructor items need to process each constructor argument.
                ConstructorReportItem constructorItem = (ConstructorReportItem)item;
                Class[] constructorArgTypes = constructorItem.getConstructorArgTypes();
                int numberOfArguments = constructorItem.getReportItems().size();
                Object[] constructorArgs = new Object[numberOfArguments];
                
                for (int argumentIndex = 0; argumentIndex < numberOfArguments; argumentIndex++) {
                    ReportItem argumentItem = (ReportItem)constructorItem.getReportItems().get(argumentIndex);
                    Object result = processItem(query, row, toManyData, argumentItem);
                    constructorArgs[argumentIndex] = ConversionManager.getDefaultManager().convertObject(result, constructorArgTypes[argumentIndex]);
                }
                try {
                    Constructor constructor = constructorItem.getConstructor();
                    Object returnValue = null;
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                        try {
                            returnValue = AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, constructorArgs));
                        } catch (PrivilegedActionException exception) {
                            throw QueryException.exceptionWhileUsingConstructorExpression(exception.getException(), query);                       }
                    } else {
                        returnValue = PrivilegedAccessHelper.invokeConstructor(constructor, constructorArgs);
                    }
                    results.add(returnValue);
                } catch (IllegalAccessException exc){
                    throw QueryException.exceptionWhileUsingConstructorExpression(exc, query);
                } catch (java.lang.reflect.InvocationTargetException exc){
                    throw QueryException.exceptionWhileUsingConstructorExpression(exc, query);
                } catch (InstantiationException exc){
                    throw QueryException.exceptionWhileUsingConstructorExpression(exc, query);
                }

            } else if (item.getAttributeExpression()!=null && item.getAttributeExpression().isClassTypeExpression()){
                Object value = processItem(query, row, toManyData, item);
                ClassDescriptor descriptor = ((org.eclipse.persistence.internal.expressions.ClassTypeExpression)item.getAttributeExpression()).getContainingDescriptor(query);
                if (descriptor !=null && descriptor.hasInheritance()){
                    value = descriptor.getInheritancePolicy().classFromValue(value, query.getSession());
                } else {
                    value = query.getSession().getDatasourcePlatform().convertObject(value, Class.class);
                }
                results.add(value);
            } else {
                // Normal items
                Object value = processItem(query, row, toManyData, item);
                results.add(value);
            }
        }

        setResults(results);
    }
    
    /**
     * INTERNAL:
     * Return a value from an item and database row (converted from raw field values using the mapping).
     */
    protected Object processItem(ReportQuery query, AbstractRecord row, Vector toManyData, ReportItem item) {
        JoinedAttributeManager joinManager = null;
        if (item.hasJoining()) {
            joinManager = item.getJoinedAttributeManager();
            if (joinManager.isToManyJoin()) {
                // PERF: Only reset data-result if unset, must only occur once per item, not per row (n vs n^2).
                if (joinManager.getDataResults_() == null) {
                    joinManager.setDataResults(new ArrayList(toManyData), query.getSession());
                }
            }
        }
        Object value = null;
        DatabaseMapping mapping = item.getMapping();
        int rowSize = row.size();
        int itemIndex = item.getResultIndex();
        ClassDescriptor descriptor = item.getDescriptor();
        if (!item.isPlaceHolder()) {
            if (descriptor == null && mapping != null){
                descriptor = mapping.getReferenceDescriptor();
            }
            if (mapping != null && (mapping.isAbstractColumnMapping() || mapping.isDirectCollectionMapping())) {
                
                if (itemIndex >= rowSize) {
                    throw QueryException.reportQueryResultSizeMismatch(itemIndex + 1, rowSize);
                }
                // If mapping is not null then it must be a direct mapping - see Reportitem.init.
                // Check for non database (EIS) records to use normal get.
                if (row instanceof DatabaseRecord) {
                    value = row.getValues().get(itemIndex);
                } else {
                    value = row.get(mapping.getField());                    
                }
                if (mapping.isAbstractColumnMapping()){
                    value = ((AbstractColumnMapping)mapping).getObjectValue(value, query.getSession());
                } else {
                    Converter converter = ((DirectCollectionMapping)mapping).getValueConverter();
                    if (converter != null){
                        value = converter.convertDataValueToObjectValue(value, query.getSession());
                    }
                }
                // GF_ISSUE_395+
                if (this.key != null) {
                    this.key.append(value);
                    this.key.append("_");
                }
            } else if (descriptor != null) {
                // Item is for an object result.
                int size = descriptor.getAllSelectionFields(query).size();
                if (itemIndex + size > rowSize) {
                    throw QueryException.reportQueryResultSizeMismatch(itemIndex + size, rowSize);
                }
                AbstractRecord subRow = row;
                // Check if at the start of the row, then avoid building a subRow.
                if (itemIndex > 0) {
                    Vector trimedFields = new NonSynchronizedSubVector(row.getFields(), itemIndex, rowSize);
                    Vector trimedValues = new NonSynchronizedSubVector(row.getValues(), itemIndex, rowSize);
                    subRow = new DatabaseRecord(trimedFields, trimedValues);
                }
                if (mapping != null && mapping.isAggregateObjectMapping()){
                    value = ((AggregateObjectMapping)mapping).buildAggregateFromRow(subRow, null, null, joinManager, query, false, query.getSession(), true);
                } else {
                    //TODO : Support prefrechedCacheKeys in report query
                    value = descriptor.getObjectBuilder().buildObject(query, subRow, joinManager);
                }
                
                // this covers two possibilities
                // 1. We want the actual Map.Entry from the table rather than the just the key
                // 2. The map key is extracted from the owning object rather than built with 
                // a specific mapping.  This could happen in a MapContainerPolicy
                if (item.getAttributeExpression().isMapEntryExpression() && mapping.isCollectionMapping()){
                    Object rowKey = null;
                    if (mapping.getContainerPolicy().isMapPolicy() && !mapping.getContainerPolicy().isMappedKeyMapPolicy()){
                        rowKey = ((MapContainerPolicy)mapping.getContainerPolicy()).keyFrom(value, query.getSession());
                    } else {
                        rowKey = mapping.getContainerPolicy().buildKey(subRow, query, null, query.getSession(), true);
                    }
                    if (((MapEntryExpression)item.getAttributeExpression()).shouldReturnMapEntry()){
                        value = new Association(rowKey, value);
                    } else {
                        value = rowKey;
                    }
                }
                // GF_ISSUE_395
                if (this.key != null) {
                    Object primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromRow(subRow, query.getSession());
                    if (primaryKey != null){//GF3233 NPE is caused by processing the null PK being extracted from referenced target with null values in database.
                        this.key.append(primaryKey);
                    }
                    this.key.append("_");
                }
            } else {
                value = row.getValues().get(itemIndex);
                // GF_ISSUE_395
                if (this.key != null) {
                    this.key.append(value);
                }
            }
        }
        return value;
    }

    /**
     * PUBLIC:
     * Clear the contents of the result.
     */
    public void clear() {
        this.names = new ArrayList<String>();
        this.results = new ArrayList<Object>();
    }

    /**
     * PUBLIC:
     * Check if the value is contained in the result.
     */
    public boolean contains(Object value) {
        return containsValue(value);
    }

    /**
     * PUBLIC:
     * Check if the key is contained in the result.
     */
    public boolean containsKey(Object key) {
        return getNames().contains(key);
    }

    /**
     * PUBLIC:
     * Check if the value is contained in the result.
     */
    public boolean containsValue(Object value) {
        return getResults().contains(value);
    }

    /**
     * OBSOLETE:
     * Return an enumeration of the result values.
     * @see #values()
     */
    public Enumeration elements() {
        return new Vector(getResults()).elements();
    }

    /**
     * PUBLIC:
     * Returns a set of the keys.
     */
    public Set entrySet() {
        return new EntrySet();
    }

    
    /**
     * Defines the virtual entrySet.
     */
    protected class EntrySet extends AbstractSet {
        public Iterator iterator() {
            return new EntryIterator();
        }
        public int size() {
            return ReportQueryResult.this.size();
        }
        public boolean contains(Object object) {
            if (!(object instanceof Entry)) {
                return false;
            }
            return ReportQueryResult.this.containsKey(((Entry)object).getKey());
        }
        public boolean remove(Object object) {
            if (!(object instanceof Entry)) {
                return false;
            }
            ReportQueryResult.this.remove(((Entry)object).getKey());
            return true;
        }
        public void clear() {
            ReportQueryResult.this.clear();
        }
    }
    
    /**
     * Entry class for implementing Map interface.
     */
    protected static class RecordEntry implements Entry {
        Object key;
        Object value;

        public RecordEntry(Object key, Object value) {
            this.key = key;
            this.value = value;
        }

        public Object getKey() {
            return key;
        }

        public Object getValue() {
            return value;
        }

        public Object setValue(Object value) {
            Object oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        public boolean equals(Object object) {
            if (!(object instanceof Map.Entry)) {
                return false;
            }
            Map.Entry entry = (Map.Entry)object;
            return compare(key, entry.getKey()) && compare(value, entry.getValue());
        }

        public int hashCode() {
            return ((key == null) ? 0 : key.hashCode()) ^ ((value == null) ? 0 : value.hashCode());
        }

        public String toString() {
            return key + "=" + value;
        }

        private boolean compare(Object object1, Object object2) {
            return (object1 == null ? object2 == null : object1.equals(object2));
        }
    }
    
    /**
     * Defines the virtual entrySet iterator.
     */
    protected class EntryIterator implements Iterator {
        int index;

        EntryIterator() {
            this.index = 0;
        }

        public boolean hasNext() {
            return this.index < ReportQueryResult.this.size();
        }

        public Object next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            this.index++;
            return new RecordEntry(getNames().get(this.index - 1), getResults().get(this.index - 1));
        }

        public void remove() {
            if (this.index >= ReportQueryResult.this.size()) {
                throw new IllegalStateException();
            }
            ReportQueryResult.this.remove(getNames().get(this.index));
        }
    }
    
    /**
     * Defines the virtual keySet iterator.
     */
    protected class KeyIterator extends EntryIterator {
        public Object next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            this.index++;
            return getNames().get(this.index - 1);
        }
    }

    /**
     * PUBLIC:
     * Compare if the two results are equal.
     */
    public boolean equals(Object anObject) {
        if (anObject instanceof ReportQueryResult) {
            return equals((ReportQueryResult)anObject);
        }

        return false;
    }

    /**
     * INTERNAL:
     * Used in testing to compare if results are correct.
     */
    public boolean equals(ReportQueryResult result) {
        if (this == result) {
            return true;
        }
        if (!getResults().equals(result.getResults())) {
            return false;
        }

        // Compare PKs
        if (getId() != null) {
            if (result.getId() == null) {
                return false;
            }
            return getId().equals(getId());
        }

        return true;
    }

    /**
     * PUBLIC:
     * Return the value for given item name.
     */
    public Object get(Object name) {
        if (name instanceof String) {
            return get((String)name);
        }

        return null;
    }

    /**
     * PUBLIC:
     * Return the value for given item name.
     */
    public Object get(String name) {
        int index = getNames().indexOf(name);
        if (index == -1) {
            return null;
        }

        return getResults().get(index);
    }

    /**
     * PUBLIC:
     * Return the indexed value from result.
     */
    public Object getByIndex(int index) {
        return getResults().get(index);
    }

    /**
     * INTERNAL:
     * Return the unique key for this result
     */
    public String getResultKey(){
        if (this.key != null){
            return this.key.toString();
        }
        return null;
    }
     
    /**
     * PUBLIC:
     * Return the names of report items, provided to ReportQuery.
     */
    public List<String> getNames() {
        return names;
    }

    /**
     * PUBLIC:
     * Return the Id for the result or null if not requested.
     */
    public Object getId() {
        return primaryKey;
    }
    
    /**
     * PUBLIC:
     * Return the PKs for the corresponding object or null if not requested.
     * @Deprecated since 2.1, replaced by getId()
     * @see #getId()
     */
    @Deprecated
    public Vector<Object> getPrimaryKeyValues() {
        if (this.primaryKey instanceof CacheId) {
            return new Vector(Arrays.asList(((CacheId)this.primaryKey).getPrimaryKey()));
        }
        Vector primaryKey = new Vector(1);
        primaryKey.add(this.primaryKey);
        return primaryKey;
    }

    /**
     * PUBLIC:
     * Return the results.
     */
    public List<Object> getResults() {
        return results;
    }

    /**
     * PUBLIC:
     * Return if the result is empty.
     */
    public boolean isEmpty() {
        return getNames().isEmpty();
    }

    /**
     * OBSOLETE:
     * Return an enumeration of the result names.
     * @see #keySet()
     */
    public Enumeration keys() {
        return new Vector(getNames()).elements();
    }
    
    /**
     * PUBLIC:
     * Returns a set of the keys.
     */
    public Set keySet() {
        return new KeySet();
    }
    
    /**
     * Defines the virtual keySet.
     */
    protected class KeySet extends EntrySet {
        public Iterator iterator() {
            return new KeyIterator();
        }
        public boolean contains(Object object) {
        return ReportQueryResult.this.containsKey(object);
        }
        public boolean remove(Object object) {
            return ReportQueryResult.this.remove(object) != null;
        }
    }

    /**
     * ADVANCED:
     * Set the value for given item name.
     */
    public Object put(Object name, Object value) {
        int index = getNames().indexOf(name);
        if (index == -1) {
            getNames().add((String)name);
            getResults().add(value);
            return null;
        }

        Object oldValue = getResults().get(index);
        getResults().set(index, value);
        return oldValue;
    }

    /**
     * PUBLIC:
     * Add all of the elements.
     */
    public void putAll(Map map) {
        Iterator entriesIterator = map.entrySet().iterator();
        while (entriesIterator.hasNext()) {
            Map.Entry entry = (Map.Entry)entriesIterator.next();
            put(entry.getKey(), entry.getValue());
        }
    }

    /**
     * PUBLIC:
     * If the PKs were retrieved with the attributes then this method can be used to read the real object from the database.
     */
    public Object readObject(Class javaClass, Session session) {
        if (getId() == null) {
            throw QueryException.reportQueryResultWithoutPKs(this);
        }

        ReadObjectQuery query = new ReadObjectQuery(javaClass);
        query.setSelectionId(getId());

        return session.executeQuery(query);
    }

    /**
     * INTERNAL:
     * Remove the name key and value from the result.
     */
    public Object remove(Object name) {
        int index = getNames().indexOf(name);
        if (index >= 0) {
            getNames().remove(index);
            Object value = getResults().get(index);
            getResults().remove(index);
            return value;
        }
        return null;
    }

    protected void setNames(List<String> names) {
        this.names = names;
    }

    /**
     * INTERNAL:
     * Set the Id for the result row's object.
     */
    protected void setId(Object primaryKey) {
        this.primaryKey = primaryKey;
    }

    /**
     * INTERNAL:
     * Set the results.
     */
    public void setResults(List<Object> results) {
        this.results = results;
    }

    /**
     * PUBLIC:
     * Return the number of name/value pairs in the result.
     */
    public int size() {
        return getNames().size();
    }

    /**
     * INTERNAL:
     * Converts the ReportQueryResult to a simple array of values.
     */
    public Object[] toArray(){
       List list = getResults();
       return (list == null) ? null : list.toArray();
    }

    /**
     * INTERNAL:
     * Converts the ReportQueryResult to a simple list of values.
     */
    public List toList(){
        return this.getResults();
    }
    
    public String toString() {
        java.io.StringWriter writer = new java.io.StringWriter();
        writer.write("ReportQueryResult(");
        for (int index = 0; index < getResults().size(); index++) {
            Object resultObj = getResults().get(index);
            writer.write(String.valueOf(resultObj));
            writer.write(" <"
                         + (resultObj == null ? "null" : resultObj.getClass().getName())
                         + ">");
            if (index < (getResults().size() - 1)) {
                writer.write(", ");
            }
        }
        writer.write(")");
        return writer.toString();
    }

    /**
     * PUBLIC:
     * Returns an collection of the values.
     */
    public Collection values() {
        return getResults();
    }
}
