/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019, 2020 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
//     10/01/2018: Will Dazey
//       - #253: Add support for embedded constructor results with CriteriaBuilder
package org.eclipse.persistence.queries;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.expressions.MapEntryExpression;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.NonSynchronizedSubVector;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.queries.ReportItem;
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.AggregateObjectMapping;
import org.eclipse.persistence.mappings.Association;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DirectCollectionMapping;
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();
        }

        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.
        }

        List<Object> results = new ArrayList<Object>();
        for(ReportItem item: query.getItems()) {
            if (item.isConstructorItem()) {
                Object result = processConstructorItem(query, row, toManyData, (ConstructorReportItem) item);
                results.add(result);
            } 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);
    }

    private Object processConstructorItem(ReportQuery query, AbstractRecord row, Vector toManyData, ConstructorReportItem constructorItem) {
        // For constructor items need to process each constructor argument.
        Class[] constructorArgTypes = constructorItem.getConstructorArgTypes();
        int numberOfArguments = constructorItem.getReportItems().size();
        Object[] constructorArgs = new Object[numberOfArguments];

        for (int argumentIndex = 0; argumentIndex < numberOfArguments; argumentIndex++) {
            ReportItem argumentItem = constructorItem.getReportItems().get(argumentIndex);
            Object result = null;
            if(argumentItem.isConstructorItem()) {
                result = processConstructorItem(query, row, toManyData, (ConstructorReportItem) argumentItem);
            } else {
                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);
            }
            return returnValue;
        } catch (ReflectiveOperationException exc) {
            throw QueryException.exceptionWhileUsingConstructorExpression(exc, query);
        }
    }

    private Object processItemFromMapping(ReportQuery query, AbstractRecord row, DatabaseMapping mapping, ReportItem item, int itemIndex) {
        Object value = null;

        // 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());
        }

        //Bug 421056: JPA 2.1; section 4.8.5
        if(item.getAttributeExpression().isFunctionExpression()) {
            FunctionExpression exp = (FunctionExpression) item.getAttributeExpression();
            int selector = exp.getOperator().getSelector();
            //a value of null for max/min implies no rows could be applied
            //we want to return null, per the spec, here before the mapping gets to alter the value
            if (value == null && ((selector == ExpressionOperator.Maximum) || (selector == ExpressionOperator.Minimum))) {
                return value;
            }
        }

        //If the mapping was set on the ReportItem, then use the mapping to convert the value
        if (mapping.isAbstractColumnMapping()) {
            value = ((AbstractColumnMapping)mapping).getObjectValue(value, query.getSession());
        } else if (mapping.isDirectCollectionMapping()) {
            value = ((DirectCollectionMapping)mapping).getObjectValue(value, query.getSession());
        }
        return value;
    }

    /**
     * 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;
        int rowSize = row.size();
        int itemIndex = item.getResultIndex();

        DatabaseMapping mapping = item.getMapping();
        ClassDescriptor descriptor = item.getDescriptor();

        if (item.getAttributeExpression() != null) {
            if (descriptor == null && mapping != null) {
                descriptor = mapping.getReferenceDescriptor();
            }
            if (mapping != null && (mapping.isAbstractColumnMapping() || mapping.isDirectCollectionMapping())) {

                if (itemIndex >= rowSize) {
                    throw QueryException.reportQueryResultSizeMismatch(itemIndex + 1, rowSize);
                }

                value = processItemFromMapping(query, row, mapping, item, itemIndex);

                // 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 = 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.
     */
    @Override
    public void clear() {
        this.names = new ArrayList<>();
        this.results = new ArrayList<>();
    }

    /**
     * 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.
     */
    @Override
    public boolean containsKey(Object key) {
        return getNames().contains(key);
    }

    /**
     * PUBLIC:
     * Check if the value is contained in the result.
     */
    @Override
    public boolean containsValue(Object value) {
        return getResults().contains(value);
    }

    /**
     * PUBLIC:
     * Returns a set of the keys.
     */
    @Override
    public Set entrySet() {
        return new EntrySet();
    }


    /**
     * Defines the virtual entrySet.
     */
    protected class EntrySet extends AbstractSet {
        @Override
        public Iterator iterator() {
            return new EntryIterator();
        }
        @Override
        public int size() {
            return ReportQueryResult.this.size();
        }
        @Override
        public boolean contains(Object object) {
            if (!(object instanceof Entry)) {
                return false;
            }
            return ReportQueryResult.this.containsKey(((Entry)object).getKey());
        }
        @Override
        public boolean remove(Object object) {
            if (!(object instanceof Entry)) {
                return false;
            }
            ReportQueryResult.this.remove(((Entry)object).getKey());
            return true;
        }
        @Override
        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;
        }

        @Override
        public Object getKey() {
            return key;
        }

        @Override
        public Object getValue() {
            return value;
        }

        @Override
        public Object setValue(Object value) {
            Object oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        @Override
        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());
        }

        @Override
        public int hashCode() {
            return ((key == null) ? 0 : key.hashCode()) ^ ((value == null) ? 0 : value.hashCode());
        }

        @Override
        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;
        }

        @Override
        public boolean hasNext() {
            return this.index < ReportQueryResult.this.size();
        }

        @Override
        public Object next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            this.index++;
            return new RecordEntry(getNames().get(this.index - 1), getResults().get(this.index - 1));
        }

        @Override
        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 {
        @Override
        public Object next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            this.index++;
            return getNames().get(this.index - 1);
        }
    }

    /**
     * PUBLIC:
     * Compare if the two results are equal.
     */
    @Override
    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;
    }

    @Override
    public int hashCode() {
        List<Object> results = getResults();
        Object id = getId();
        int result = results != null ? results.hashCode() : 0;
        result = 31 * result + (id != null ? id.hashCode() : 0);
        return result;
    }

    /**
     * PUBLIC:
     * Return the value for given item name.
     */
    @Override
    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 results.
     */
    public List<Object> getResults() {
        return results;
    }

    /**
     * PUBLIC:
     * Return if the result is empty.
     */
    @Override
    public boolean isEmpty() {
        return getNames().isEmpty();
    }

    /**
     * PUBLIC:
     * Returns a set of the keys.
     */
    @Override
    public Set keySet() {
        return new KeySet();
    }

    /**
     * Defines the virtual keySet.
     */
    protected class KeySet extends EntrySet {
        @Override
        public Iterator iterator() {
            return new KeyIterator();
        }
        @Override
        public boolean contains(Object object) {
        return ReportQueryResult.this.containsKey(object);
        }
        @Override
        public boolean remove(Object object) {
            return ReportQueryResult.this.remove(object) != null;
        }
    }

    /**
     * ADVANCED:
     * Set the value for given item name.
     */
    @Override
    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.
     */
    @Override
    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.
     */
    @Override
    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.
     */
    @Override
    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();
    }

    @Override
    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.
     */
    @Override
    public Collection values() {
        return getResults();
    }
}
