/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.flex.compiler.internal.tree.as;

import org.apache.flex.abc.semantics.Name;
import org.apache.flex.compiler.common.DependencyType;
import org.apache.flex.compiler.definitions.IDefinition;
import org.apache.flex.compiler.definitions.ITypeDefinition;
import org.apache.flex.compiler.definitions.references.INamespaceReference;
import org.apache.flex.compiler.definitions.references.IReference;
import org.apache.flex.compiler.internal.scopes.ASScope;
import org.apache.flex.compiler.internal.scopes.WithScope;
import org.apache.flex.compiler.projects.ICompilerProject;
import org.apache.flex.compiler.tree.ASTNodeID;
import org.apache.flex.compiler.tree.as.IASNode;
import org.apache.flex.compiler.tree.as.IExpressionNode;
import org.apache.flex.compiler.tree.as.IScopedNode;

/**
 * ActionScript parse tree node representing an expression
 */
public abstract class ExpressionNodeBase extends FixedChildrenNode implements IExpressionNode
{
    private static final int FLAG_HAS_PARENS = 0x8000;
    
    private static final int FLAG_TREAT_AS_PACKAGE = 0x4000;
    
    /**
     * Constructor.
     */
    public ExpressionNodeBase()
    {
    }

    /**
     * Copy constructor.
     * 
     * @param other The node to copy.
     */
    protected ExpressionNodeBase(ExpressionNodeBase other)
    {
        this.flags = other.flags;
        //this.fParent = other.fParent;
        this.setSourcePath(other.getSourcePath());
        this.setLine(other.getLine());
        this.setColumn(other.getColumn());
        this.setStart(other.getAbsoluteStart());
        this.setEnd(other.getAbsoluteEnd());
        this.setEndLine(other.getEndLine());
        this.setEndColumn(other.getEndColumn());
    }

    protected int flags;
    
    //
    // NodeBase overrides
    //
    
    /**
     * Normalize the tree. Move custom children into the real child list and
     * fill in missing offsets so that offset lookup will work. Used during
     * parsing.
     */
    @Override
    public void normalize(boolean fillInOffsets)
    {
        setChildren(fillInOffsets);
        
        // The list of children doesn't change, so the child count should be constant throughout the loop
        int childrenSize = getChildCount();
        
        // Normalize the regular children
        for (int i = 0; i < childrenSize; i++)
        {
            IASNode child = getChild(i);
            if (child instanceof NodeBase)
                ((NodeBase)child).normalize(fillInOffsets);
        }
        
        if (fillInOffsets)
            fillInOffsets();
    }
    
    @Override
    public ASScope getASScope()
    {
        ASScope scope = super.getASScope();

        if (scope instanceof WithScope)
        {
            // If this expression is part of the target expression of a with node
            // then we want the scope containing the with scope, not the with scope itself.
            IExpressionNode baseExpr = this.getDecorationNode();
            IASNode parent = baseExpr.getParent();
            if (parent instanceof WithNode)
            {
                WithNode withParent = (WithNode)parent;
                if (withParent.getTargetNode() == baseExpr)
                {
                    return withParent.getASScope();
                }
            }
        }
        return scope;
    }
    
    //
    // IExpressionNode implementations
    //
    
    @Override
    public IDefinition resolve(ICompilerProject project)
    {
        // For all expression nodes except for the MemberAccessExpressionNode and the IdentifierNode,
        // this method returns null.
        return null;
    }

    @Override
    public ITypeDefinition resolveType(ICompilerProject project)
    {
        // TODO: implement for every expression type - currently only works for IdentifierNodes
        return null;
    }
    
    @Override
    public boolean isDynamicExpression(ICompilerProject project)
    {
        boolean isDynamic = true;

        ITypeDefinition type = resolveType(project);
        if (type != null)
            isDynamic = type.isDynamic();

        return isDynamic;
    }
    
    public ExpressionNodeBase copyForInitializer(IScopedNode scopedNode)
    {
        ExpressionNodeBase newExpr = copy();
        
        if (newExpr != null)
        {
            // If we copied the expression successfully,
            // set up all the parent pointers within the new subtree.
            if (scopedNode instanceof NodeBase)
            {
                NodeBase node = (NodeBase) scopedNode;
                newExpr.setParent(node);
            }
            newExpr.normalize(false);
        }
        
        return newExpr;
    }

    @Override
    public boolean hasParenthesis()
    {
        return (flags & FLAG_HAS_PARENS) != 0;
    }
    
    //
    // Other methods
    //

    /**
     * Copy the ExpressionNodeBase and its subtree.
     * 
     * @return  a new ExpressionNodeBase that represents the same content as the original node
     */
    protected abstract ExpressionNodeBase copy();

    /**
     * Gets the AET {@link Name} object to be used for an expression.
     * <p>
     * For all expression nodes except for the identifier nodes and member
     * access nodes, this method returns <code>null</code>.
     * <p>
     * This is the method that the code generator calls to determine what name
     * to emit into the ABC file. It will handle resolving the identifier if
     * necessary and generating the appropriate qname or multiname.
     * 
     * @param project The {@link ICompilerProject} to use to do lookups.
     * @return A AET {@link Name} object.
     */
    public Name getMName(ICompilerProject project)
    {
        return null;
    }

    public void setHasParenthesis(boolean hasParens)
    {
        if (hasParens)
            flags |= FLAG_HAS_PARENS;
        else
            flags &= ~FLAG_HAS_PARENS;
    }

    /**
     * Determine if this node is a reference to a package
     * 
     * @return true if this node is really a package reference.
     */
    public boolean isPackageReference()
    {
        // Return true if we're somewhere that MXML doesn't require packages to be imported
        if (getTreatAsPackage())
            return true;

        boolean isPackage = false;
        if (this.getBaseExpression() == null)
        {
            // Only check for packages if we don't have a base expression.
            // in a.b.c, 'a', 'a.b', or 'a.b.c' could be package names, but not 'c' or 'b.c'
            String ref = this.computeSimpleReference();
            if (ref != null)
            {
                ASScope scope = getASScope();

                if (scope.isPackageName(ref))
                    isPackage = true;
            }
        }
        return isPackage;
    }
    
    /**
     * Get the base expression, if any. In <code>a.b</code>, or
     * <code>a.@b</code>, or <code>a.c::b</code>, the base of <code>b</code> is
     * <code>a</code>.
     * 
     * @return The base as an ExpressionNodeBase, if it is one, otherwise null
     */
    public ExpressionNodeBase getBaseExpression()
    {
        ExpressionNodeBase parent = getParentExpression();

        if (parent != null)
            return parent.getBaseForMemberRef(this);

        return null;
    }

    /**
     * @return true if this ExpressionNodeBase is in a with scope.
     */
    public boolean inWith()
    {
        ASScope scope = getASScope();
        return scope != null ? scope.isInWith() : false;
    }

    /**
     * Get the appropriate node at which to start decoration. This returns the
     * largest containing expression node, which should provide enough context
     * to figure out what the definitions are.
     * 
     * @return the node that should be decorated
     */
    public ExpressionNodeBase getDecorationNode()
    {
        IASNode current = this;
        while (current.getParent() != null && current.getParent() instanceof ExpressionNodeBase)
            current = current.getParent();
        return (ExpressionNodeBase)current;
    }
    
    /**
     * Check if the expression is inside a filter expression. For example:
     * 
     * <pre>
     * xmlData.(getName() == "hello")
     * </pre>
     * 
     * {@code getName() == "hello"} is in a filter.
     * <p>
     * The implementation walks up the parent nodes till the first
     * {@link ScopedBlockNode}. If a {@link MemberAccessExpressionNode} with
     * {@link ASTNodeID#E4XFilterID} is found, this node is inside a filter
     * expression.
     * 
     * @return True if this node is in a filter expression.
     */
    public final boolean inFilter()
    {
        IASNode parent = this.getParent();
        while (parent != null && !(parent instanceof ScopedBlockNode))
        {
            if (parent.getNodeID() == ASTNodeID.E4XFilterID)
                return true;
            else
                parent = parent.getParent();
        }
        return false;
    }
    
    /**
     * Get the parent of this Node as an ExpressionNodeBase.
     * 
     * @return the parent of this node as an ExpressionNodeBase, or null if it isn't
     * an ExpressionNodeBase.
     */
    protected ExpressionNodeBase getParentExpression()
    {
        IASNode p = getParent();
        return p instanceof ExpressionNodeBase ? (ExpressionNodeBase)p : null;
    }

    /**
     * Generate a simple reference - this is a String representing a name that
     * can be resolved with the set of open namespaces. If such a simple
     * reference can't be generated for this expression, null is returned.
     * 
     * @return A String representing the simple name that represents this node,
     * or null if no simple name can be obtained.
     */
    String computeSimpleReference()
    {
        return null;
    }

    /**
     * Generate an IReference that can serve as the type reference for something
     * like a type annotation, baseclass reference, interface reference, etc.
     * 
     * @return An IReference that represents this expression node or null.
     */
    IReference computeTypeReference()
    {
        return null;
    }

    /**
     * Generate an INamespaceReference that can serve as the namespace reference for something
     * like a namespace initializer.
     *
     * @return An INamespaceReference that represents this expression node or null.
     */
    public INamespaceReference computeNamespaceReference()
    {
        return null;
    }

    boolean isPartOfMemberRef(ExpressionNodeBase e)
    {
        return false;
    }

    ExpressionNodeBase getBaseForMemberRef(ExpressionNodeBase e)
    {
        return null;
    }

    boolean isQualifiedExpr(ExpressionNodeBase e)
    {
        return false;
    }

    ExpressionNodeBase getQualifier(ExpressionNodeBase e)
    {
        return null;
    }

    /**
     * Determine if e is part of an attribute expression
     */
    boolean isAttributeExpr(ExpressionNodeBase e)
    {
        return false;
    }

    private boolean getTreatAsPackage()
    {
        return (flags & FLAG_TREAT_AS_PACKAGE) != 0;
    }

    /**
     * When set to true, this expression will always be treated as a package -
     * the set of imports will not be checked. This is needed for some MXML
     * processing that did not require a user to import a package before using
     * it as a package (instead everything to the left of the last dot was
     * considered a package) e.g. 'a.b.Foo' would treat 'a.b' as a package name.
     * 
     * @param b the new Value of treatAsPackage
     */
    void setTreatAsPackage(boolean b)
    {
        if (b)
            flags |= FLAG_TREAT_AS_PACKAGE;
        else
            flags &= ~FLAG_TREAT_AS_PACKAGE;
    }

    /**
     * Compute the type of dependency between two compilation unit this
     * expression node creates.
     *
     * @return The type of dependency between two compilation unit this
     * identifier node creates.
     */
    public DependencyType getDependencyType()
    {
        // TODO We'd really like to make this method not dependent on the AST shape.
        // In an ideal world the parser would use information it has while building the tree to
        // compute the dependency type or some other value that can be trivially used to compute the
        // dependency type.
        final IASNode parent = getParent();

        // 
        // If we're part of an expression, then ask our parent expression what type
        // of dependency we are.
        // should handle things like the node for 'Bar' in:
        //    var t:Vector.<Vector.<Bar>>;
        //
        if( parent instanceof ExpressionNodeBase )
            return ((ExpressionNodeBase)parent).getDependencyType();

        // If the this node is part of the extends or implements expressions of a class
        // then this node creates an inheritance dependency.
        if (parent instanceof ClassNode && this == ((ClassNode)parent).getBaseClassNode())
            return DependencyType.INHERITANCE;
        if (parent instanceof ContainerNode && parent.getParent() instanceof ClassNode && parent == ((ClassNode)parent.getParent()).getInterfacesNode())
            return DependencyType.INHERITANCE;
        if (parent instanceof ContainerNode && parent.getParent() instanceof InterfaceNode && parent == ((InterfaceNode)parent.getParent()).getBaseInterfacesNode())
            return DependencyType.INHERITANCE;

        // Why we are resolving the identifier node that is the name of a class is beyond me,
        // but might we'll treat that as a signature dependency.
        if (parent instanceof ClassNode && this == ((ClassNode)getParent()).getNameExpressionNode())
            return DependencyType.SIGNATURE;

        // Identifier nodes referred to directly by a FunctionNode
        // or ParameterNode create signature dependencies unless
        // the FunctionNode is itself inside of an other FunctionNode.
        FunctionNode functionContainingReference = null;
        if (parent instanceof FunctionNode)
        {
            FunctionNode parentFunction = (FunctionNode)parent;
            if (this == parentFunction.getReturnTypeNode())
                functionContainingReference = parentFunction;
        }
        else if (parent instanceof ParameterNode)
        {
            if (this == ((ParameterNode)parent).getTypeNode())
            {
                IASNode tempNode = parent.getParent().getParent();
                if (tempNode instanceof FunctionNode)
                    functionContainingReference = (FunctionNode)tempNode;
                    // We might be in a catch node, in which case we should be ane
                    // expression dep, as theres no way a catch could influence the signature
                else if (parent.getParent() instanceof CatchNode)
                    return DependencyType.EXPRESSION;
            }
        }
        if (functionContainingReference != null)
        {
            IASNode outerFunction = functionContainingReference.getAncestorOfType(FunctionNode.class);
            if (outerFunction != null)
                return DependencyType.EXPRESSION;
            else
                return DependencyType.SIGNATURE;
        }

        // Identifier nodes that are the type annotation of a definition
        // are signature dependencies unless they are inside of a FunctionNode.
        if (parent instanceof BaseTypedDefinitionNode && this == ((BaseTypedDefinitionNode)parent).getTypeNode())
        {
            assert !((parent instanceof FunctionNode) || (parent instanceof ParameterNode));
            // variable or const type annotation
            // If we are in a function this is an expression dep, otherwise it is a signature dep.
            FunctionNode functionContainingIdentifier = (FunctionNode)getAncestorOfType(FunctionNode.class);
            if (functionContainingIdentifier != null)
                return DependencyType.EXPRESSION;
            else
                return DependencyType.SIGNATURE;
        }

        // don't add a dependency because of an import stmt.  The parent will always be an ImportNode
        // regardless of import tree shape, such as:
        // import foo;
        // import p.foo;
        // import p.*;
        if (parent instanceof ImportNode)
            return null;

        // Anything not handled by the above cases is an expression dependency.
        return DependencyType.EXPRESSION;
    }
}
