/*******************************************************************************
 * 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:
 *     tware - initial implementation
 ******************************************************************************/  
package org.eclipse.persistence.internal.expressions;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.InterfaceContainerPolicy;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.querykeys.ForeignReferenceQueryKey;
import org.eclipse.persistence.mappings.querykeys.QueryKey;
import org.eclipse.persistence.queries.ReadQuery;

public class MapEntryExpression extends QueryKeyExpression {

    protected boolean returnMapEntry = false;
    
    public MapEntryExpression(Expression base) {
        this();
        this.baseExpression = base;
    }
    
    public MapEntryExpression() {
        this.shouldQueryToManyRelationship = true;
        this.hasQueryKey = true;
        this.hasMapping = false;
    }
    
    /**
     * INTERNAL:
     * Find the alias for a given table.  A TableEntry is a place holder and its base expression holds
     * all the relevant information.  Get the alias from the baseExpression
     */
    @Override
    public DatabaseTable aliasForTable(DatabaseTable table) {
        return ((DataExpression)getBaseExpression()).aliasForTable(table);
    }
    
    /**
     * Set this expression to represent a Map.Entry rather than the Map's key
     */
    public void returnMapEntry(){
        returnMapEntry = true;
    }
    
    /**
     * INTERNAL:
     * This expression is built on a different base than the one we want. Rebuild it and
     * return the root of the new tree
     */
    @Override
    public Expression rebuildOn(Expression newBase) {
        Expression newLocalBase = getBaseExpression().rebuildOn(newBase);
        Expression result = null;
        
        if (returnMapEntry){
            result = newLocalBase.mapEntry();
        } else {
            result = newLocalBase.mapKey();
        }

        result.setSelectIfOrderedBy(selectIfOrderedBy());
        return result;
    }
    
    /**
     * INTERNAL:
     * A special version of rebuildOn where the newBase need not be a new
     * ExpressionBuilder but any expression.
     * <p>
     * For nested joined attributes, the joined attribute query must have
     * its joined attributes rebuilt relative to it.
     */
    @Override
    public Expression rebuildOn(Expression oldBase, Expression newBase) {
        if (this == oldBase) {
            return newBase;
        }
        Expression newLocalBase = ((QueryKeyExpression)getBaseExpression()).rebuildOn(oldBase, newBase);
        Expression result = null;

        if (returnMapEntry){
            result = newLocalBase.mapEntry();
        } else {
            result = newLocalBase.mapKey();
        }
        result.setSelectIfOrderedBy(selectIfOrderedBy());
        return result;
    }
    
    /**
     * INTERNAL:
     * Used for debug printing.
     */
    @Override
    public String descriptionOfNodeType() {
        if (returnMapEntry){
            return "MapEntry";
        } else {
            return "MapKey";
        }
    }
    
    /**
     * INTERNAL:
     */
    @Override
    public Expression existingDerivedTable(DatabaseTable table) {
        if (baseExpression.isDataExpression()){
            return ((DataExpression)baseExpression).existingDerivedTable(table);
        }
        return super.existingDerivedTable(table);
    }
    
    /**
     * Exclude any tables defined by base.
     */
    @Override
    public List<DatabaseTable> getOwnedTables() {
        return null;
    }

    @Override
    public ClassDescriptor getDescriptor() {
        if (isAttribute()) {
            return null;
        }
        if (descriptor == null) {
            // Look first for query keys, then mappings. Ultimately we should have query keys
            // for everything and can dispense with the mapping part.
            ForeignReferenceQueryKey queryKey = (ForeignReferenceQueryKey)getQueryKeyOrNull();
            if (queryKey != null) {
                descriptor = getSession().getDescriptor(queryKey.getReferenceClass());
                return descriptor;
            }
            if (getMapping() == null) {
                throw QueryException.invalidQueryKeyInExpression(this);
            }

            // We assume this is either a foreign reference or an aggregate mapping
            descriptor = getMapping().getContainerPolicy().getDescriptorForMapKey();
            if (getMapping().isVariableOneToOneMapping()) {
                throw QueryException.cannotQueryAcrossAVariableOneToOneMapping(getMapping(), descriptor);
            }
        }
        return descriptor;
    }
    
    /**
     * INTERNAL:
     */
    @Override
    public DatabaseField getField() {
        if (!isAttribute()) {
            return null;
        }
        DatabaseField field = getInterfaceContainerPolicy().getDirectKeyField(getMapping());
        return field;
    }
    
    /**
     * INTERNAL:
     * Return all the fields
     */
    @Override
    public Vector getFields() {
        Vector result = new Vector();
        InterfaceContainerPolicy icp = getInterfaceContainerPolicy();
        // if this is a map entry get all the fields for both the key and the value
        if (returnMapEntry || !icp.isMappedKeyMapPolicy()){
            result.addAll(getBaseExpression().getFields());
        } else if (isAttribute()) {
            DatabaseField field = getField();
            if (field != null) {
                result.add(field);
            }
        } else {
            result.addAll(getInterfaceContainerPolicy().getAdditionalFieldsForJoin(getMapping()));
        }
        return result;
    }

    /**
     * INTERNAL:
     */
    @Override
    public List<DatabaseField> getSelectionFields(ReadQuery query) {
        ArrayList<DatabaseField> result = new ArrayList<DatabaseField>();
        InterfaceContainerPolicy icp = getInterfaceContainerPolicy();
        // if this is a map entry get all the fields for both the key and the value
        if (returnMapEntry || !icp.isMappedKeyMapPolicy()){
            result.addAll(getBaseExpression().getSelectionFields(query));
        } else if (isAttribute()) {
            DatabaseField field = getField();
            if (field != null) {
                result.add(field);
            }
        } else {
            result.addAll(getInterfaceContainerPolicy().getAdditionalFieldsForJoin(getMapping()));
        }
        return result;
    }

    @Override
    public CollectionMapping getMapping() {
        return (CollectionMapping)((QueryKeyExpression)getBaseExpression()).getMapping();
    }

    @Override
    public QueryKey getQueryKeyOrNull() {
        if (!hasQueryKey) {
            return null;
        }
        
        InterfaceContainerPolicy cp = getInterfaceContainerPolicy();
        if (queryKey == null) {
            if (returnMapEntry){
                return null;
            } else {
                queryKey = cp.createQueryKeyForMapKey();
            }
        }
        return queryKey;

    }

    /**
     * INTERNAL:
     * Return if the expression is for a direct mapped attribute.
     */
    @Override
    public boolean isAttribute() {
        if (isAttributeExpression == null) {
            if (returnMapEntry){
                return false;
            }
            InterfaceContainerPolicy containerPolicy = getInterfaceContainerPolicy();
            return containerPolicy.isMapKeyAttribute();

        }
        return isAttributeExpression.booleanValue();
    }
    
    /**
     * INTERNAL:
     */
    @Override
    public boolean isMapEntryExpression(){
        return true;
    }

    private InterfaceContainerPolicy getInterfaceContainerPolicy(){
        DatabaseMapping mapping = getMapping();
        if (mapping == null) {
            throw QueryException.noMappingForMapEntryExpression(getBaseExpression());
        }

        if (!mapping.isCollectionMapping()){
            throw QueryException.mapEntryExpressionForNonCollection(getBaseExpression(), getMapping());
        }
        InterfaceContainerPolicy cp = null;
        try{
            cp = (InterfaceContainerPolicy)getMapping().getContainerPolicy();
        } catch (ClassCastException e){
            throw QueryException.mapEntryExpressionForNonMap(getBaseExpression(), getMapping());
        }
        return cp;
    }
    
    /**
     * INTERNAL:
     * Mapping criteria will be provided by the base expression
     */
    @Override
    public Expression mappingCriteria(Expression base) {
        return null;
    }

    public boolean shouldReturnMapEntry(){
        return returnMapEntry;
    }

    
    /**
     * Do any required validation for this node. Throw an exception if it's incorrect.
     */
    @Override
    public void validateNode() {
        if ((getQueryKeyOrNull() == null) && (getMapping() == null)) {
            throw QueryException.invalidQueryKeyInExpression(getName());
        }
        if (!getMapping().isCollectionMapping()) {
            throw QueryException.mapEntryExpressionForNonCollection(getBaseExpression(), getMapping());
        }
        ContainerPolicy cp = getMapping().getContainerPolicy();
        if ((cp == null) || !cp.isMapPolicy()) {
            throw QueryException.mapEntryExpressionForNonMap(getBaseExpression(), getMapping());
        }
    }
    
    /**
     * INTERNAL:
     * Used to print a debug form of the expression tree.
     */
    @Override
    public void writeDescriptionOn(BufferedWriter writer) throws IOException {
        writer.write(descriptionOfNodeType());
    }

}

