/*
 * Copyright (c) 1998, 2019 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 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:
//     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 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<>();
        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());
    }

}

