/*
 *
 *  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.royale.compiler.internal.definitions;

import java.util.Iterator;

import org.apache.royale.compiler.definitions.IAccessorDefinition;
import org.apache.royale.compiler.definitions.IClassDefinition;
import org.apache.royale.compiler.definitions.IDefinition;
import org.apache.royale.compiler.definitions.IFunctionDefinition;
import org.apache.royale.compiler.definitions.IGetterDefinition;
import org.apache.royale.compiler.definitions.IInterfaceDefinition;
import org.apache.royale.compiler.definitions.INamespaceDefinition;
import org.apache.royale.compiler.definitions.IPackageDefinition;
import org.apache.royale.compiler.definitions.IScopedDefinition;
import org.apache.royale.compiler.definitions.ISetterDefinition;
import org.apache.royale.compiler.definitions.references.INamespaceReference;
import org.apache.royale.compiler.internal.as.codegen.BindableHelper;
import org.apache.royale.compiler.internal.scopes.ASScope;
import org.apache.royale.compiler.problems.DuplicateFunctionDefinitionProblem;
import org.apache.royale.compiler.problems.UnresolvedNamespaceProblem;
import org.apache.royale.compiler.projects.ICompilerProject;
import org.apache.royale.compiler.scopes.IDefinitionSet;
import org.apache.royale.compiler.tree.as.IVariableNode;

/**
 * {@code AccessorDefinition} is the abstract base class for definitions that
 * represent getters and setters.
 */
public abstract class AccessorDefinition extends FunctionDefinition implements IAccessorDefinition
{
    public AccessorDefinition(String name)
    {
        super(name);
    }

    @Override
    public AccessorDefinition resolveCorrespondingAccessor(ICompilerProject project)
    {
        IDefinition parent = getParent();

        if (parent instanceof IClassDefinition)
        {
            // This accessor is in a class, so look for a corresponding one
            // in this class and then in all superclasses.
            Iterator<IClassDefinition> iter = ((IClassDefinition)parent).classIterator(project, true);
            while (iter.hasNext())
            {
                IClassDefinition cls = iter.next();

                AccessorDefinition correspondingAccessor =
                        findCorrespondingAccessor(cls, project);

                if (correspondingAccessor != null)
                    return correspondingAccessor;
            }
        }
        else if (parent instanceof IInterfaceDefinition)
        {
            // This accessor is in an interface, so look for a corresponding one
            // in this interface and then in all superinterfaces.
            Iterator<IInterfaceDefinition> iter = ((IInterfaceDefinition)parent).interfaceIterator(project, true);
            while (iter.hasNext())
            {
                IInterfaceDefinition intf = iter.next();

                AccessorDefinition correspondingAccessor =
                        findCorrespondingAccessor(intf, project);

                if (correspondingAccessor != null)
                    return correspondingAccessor;
            }
        }
        else if (parent instanceof IPackageDefinition)
        {
            IPackageDefinition pd = (IPackageDefinition)parent;
            return findCorrespondingAccessor(pd, project);
        }
        else if (parent == null)
        {
            // if the parent definition is null, we must be at file scope, so must search the scope 
            // directly
            ASScope scope = this.getContainingASScope();
            return findCorrespondingAccessor(scope, project);
        }
        else
            assert false; // we should have code for all cases...

        return null;
    }

    /**
     * Looks in a specified class or interface for an accessor that corresponds
     * to "this". i.e. if "this" is a getter, find the matching setter.
     * 
     * @param type is the definition to search for corresponding def
     * @return an accessor definition that matches, or null if none found
     */

    private AccessorDefinition findCorrespondingAccessor(IScopedDefinition type, ICompilerProject project)
    {
        final ASScope scope = (ASScope)type.getContainedScope();
        return findCorrespondingAccessor(scope, project);
    }

    /**
     * Looks in a specified scope for an accessor that corresponds to "this".
     * i.e. if "this" is a getter, find the matching setter.
     * 
     * @param scope is the scope to search for corresponding def
     * @return an accessor definition that matches, or null if none found
     */

    private AccessorDefinition findCorrespondingAccessor(ASScope scope, ICompilerProject project)
    {
        final String name = getBaseName();
        final INamespaceReference namespaceReference = getNamespaceReference();
        final boolean isStatic = isStatic();
        
        // If the namespace is bad and dosn't resolve, then we can't find corresponding accessor.
        final INamespaceDefinition thisNamespaceDef = namespaceReference.resolveNamespaceReference(project);
        if (thisNamespaceDef == null)
            return null; 
        final boolean isBindable = ((NamespaceDefinition)thisNamespaceDef).getAETNamespace().getName().equals(
                                    BindableHelper.bindableNamespaceDefinition.getAETNamespace().getName());

        final IDefinitionSet definitionSet = scope.getLocalDefinitionSetByName(name);

        if (definitionSet == null)
            return null;
        
        final boolean isCustomNamespace = !isBindable && !((NamespaceDefinition) thisNamespaceDef).isLanguageNamespace();

        final int n = definitionSet.getSize();
        for (int i = 0; i < n; i++)
        {
            IDefinition d = definitionSet.getDefinition(i);
            if (d instanceof IAccessorDefinition)
            {
                final IAccessorDefinition definition = (IAccessorDefinition)d;
                
                // If this is a static accessor, we want another static accessor.
                // If this is an instance accessor, we want another instance accessor. 
                if (definition.isStatic() == isStatic)
                {
                    // If this is a getter, we want a setter, and vice versa.
                    if (this instanceof IGetterDefinition && definition instanceof ISetterDefinition ||
                        this instanceof ISetterDefinition && definition instanceof IGetterDefinition)
                    {
                        INamespaceReference testDefRef = definition.getNamespaceReference();
                        INamespaceDefinition testNamespaceDef = testDefRef.resolveNamespaceReference(project);
                        if (testNamespaceDef == null)
                        {
                        	project.getProblems().add(new UnresolvedNamespaceProblem(definition.getNode()));
                        	return null;
                        }
                        final boolean testBindable = ((NamespaceDefinition)testNamespaceDef).getAETNamespace().getName().equals(
                                BindableHelper.bindableNamespaceDefinition.getAETNamespace().getName());
                        /* aharui: namespaces shouldn't have to match.  A subclass may only override
                         * one of the protected methods, and it was legal to have a public getter with
                         * a protected setter and other combinations like that.  Either both
                         * have to be in the bindable namespace, or both are not. */
                        //follow-up: (re mismatched names) The above was true for legacy Flex compiler, but is actually not currently true for ASC 2.0
                        //there are benefits to matching the legacy behavior though.
                        //for custom namespaces however, they must match
                        if (isBindable && testBindable) return (AccessorDefinition)definition;
                        
                        if (!isBindable && !testBindable) {
                            if (isCustomNamespace) {
                                //it does need to match precisely
                                if (thisNamespaceDef.equals(testNamespaceDef))
                                    return (AccessorDefinition)definition;
                            } else {
                                //match loosely based on any language namespace, but check for local conflicts first
                                if (definition.getNamespaceReference().isLanguageNamespace()) {
                                    if (!hasConflictingLanguageNSDefinition(definitionSet, this, project))
                                        return (AccessorDefinition) definition;
                                    else return null;
                                }
                            }
                        }
                    }
                }
            }
        }

        return null;
    }
    
    public boolean isProblematic() {
        return problematic;
    }
    
    public void setIsProblematic(boolean value) {
        problematic = value;
    }
    
    private boolean problematic;
    private boolean hasConflictingLanguageNSDefinition(IDefinitionSet definitionSet , IAccessorDefinition def, ICompilerProject project) {
        final boolean isGetter = def instanceof IGetterDefinition;
        final int size = definitionSet.getSize();
        int defIndex = -1;
        for (int i=0; i<size; i++) {
            IDefinition localDef = definitionSet.getDefinition(i);
            if (!(localDef instanceof IAccessorDefinition)) continue;
            IAccessorDefinition check = (IAccessorDefinition) localDef;
            if (check == def) {
                defIndex = i;
                break;
            }
        }
        if (defIndex == -1) return false;
        for (int i=0; i<defIndex; i++) {
            IDefinition localDef = definitionSet.getDefinition(i);
            if (!(localDef instanceof IAccessorDefinition)) continue;
            IAccessorDefinition check = (IAccessorDefinition) localDef;
            boolean validCheck = isGetter ? check instanceof IGetterDefinition : check instanceof ISetterDefinition;
            if (!validCheck) continue;
            if (check.getNamespaceReference().isLanguageNamespace()) {
                if (!problematic) {
                    ((AccessorDefinition) check).problematic = true;
                    //checking occurs twice, don't add multiple duplicate problems for the same check
                    problematic = true;
                    project.getProblems().add(new DuplicateFunctionDefinitionProblem(getNode().getNameExpressionNode(), this.getBaseName()));
                }
                return true;
            }
        }
        return false;
    }

    /**
     * Get the classification for this variable (local, argument, class member,
     * etc)
     * 
     * @return variable classification
     */
    @Override
    public VariableClassification getVariableClassification()
    {
        IDefinition parent = getParent();

        if (parent instanceof IFunctionDefinition)
            return VariableClassification.LOCAL;
        if (parent instanceof IClassDefinition)
            return VariableClassification.CLASS_MEMBER;
        if (parent instanceof IInterfaceDefinition)
            return VariableClassification.INTERFACE_MEMBER;
        if (parent instanceof IPackageDefinition)
            return VariableClassification.PACKAGE_MEMBER;
        if (parent == null)
        {
            if (inPackageNamespace())
                return VariableClassification.PACKAGE_MEMBER;

            return VariableClassification.FILE_MEMBER;
        }

        assert false;
        return null;
    }

    @Override
    public IVariableNode getVariableNode()
    {
        return (IVariableNode)super.getNode();
    }

    @Override
    public Object resolveInitialValue(ICompilerProject project)
    {
        return null;
    }

    @Override
    public boolean inlineFunction()
    {
        // if inlining has been enabled, don't need to check
        // for inline keyword, as inline all getters/setters
        // as long as they meet the correct criteria.
        if (canFunctionBeInlined())
            return true;

        return false;
    }
}
