/*
 *
 *  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.units;


import static com.google.common.collect.Collections2.transform;

import java.util.Collection;
import java.util.HashSet;
import org.apache.royale.compiler.css.ICSSDocument;
import org.apache.royale.compiler.filespecs.IFileSpecification;
import org.apache.royale.compiler.internal.as.codegen.CodeGeneratorManager;
import org.apache.royale.compiler.internal.definitions.ClassDefinition;
import org.apache.royale.compiler.internal.parsing.as.OffsetCue;
import org.apache.royale.compiler.internal.parsing.as.OffsetLookup;
import org.apache.royale.compiler.internal.parsing.mxml.MXMLScopeBuilder;
import org.apache.royale.compiler.internal.projects.CompilerProject;
import org.apache.royale.compiler.internal.projects.DefinitionPriority;
import org.apache.royale.compiler.internal.projects.RoyaleProject;
import org.apache.royale.compiler.internal.scopes.MXMLFileScope;
import org.apache.royale.compiler.internal.scopes.TypeScope;
import org.apache.royale.compiler.internal.tree.mxml.MXMLDocumentNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLFileNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLTreeBuilder;
import org.apache.royale.compiler.internal.units.requests.ASFileScopeRequestResult;
import org.apache.royale.compiler.internal.units.requests.SWFTagsRequestResult;
import org.apache.royale.compiler.internal.units.requests.SyntaxTreeRequestResult;
import org.apache.royale.compiler.mxml.IMXMLData;
import org.apache.royale.compiler.mxml.IMXMLDataManager;
import org.apache.royale.compiler.problems.ICompilerProblem;
import org.apache.royale.compiler.problems.UnexpectedExceptionProblem;
import org.apache.royale.compiler.tree.mxml.IMXMLFileNode;
import org.apache.royale.compiler.tree.mxml.IMXMLStyleNode;
import org.apache.royale.compiler.units.requests.IABCBytesRequestResult;
import org.apache.royale.compiler.units.requests.IFileScopeRequestResult;
import org.apache.royale.compiler.units.requests.IOutgoingDependenciesRequestResult;
import org.apache.royale.compiler.units.requests.ISWFTagsRequestResult;
import org.apache.royale.compiler.units.requests.ISyntaxTreeRequestResult;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

public class MXMLCompilationUnit extends CompilationUnitBase
{
    public MXMLCompilationUnit(CompilerProject project, String path,
                               DefinitionPriority.BasePriority basePriority,
                               int order,
                               String qname)
    {
        super(project, path, basePriority, qname);
        this.qname = qname;
        ((DefinitionPriority)getDefinitionPriority()).setOrder(order);
    }

    // The fully-qualified name of the one externally-visible definition
    // expected to be found in this compilation unit, or null if none is expected.
    // This qname is determined from the name of the file
    // and the file's location relative to the source path.
    private final String qname;

    @Override
    public UnitType getCompilationUnitType()
    {
        return UnitType.MXML_UNIT;
    }

    @Override
    protected ISyntaxTreeRequestResult handleSyntaxTreeRequest() throws InterruptedException
    {
        // Fulfill other requests before profiling this request.       
        final IFileScopeRequestResult fileScopeRequestResult = getFileScopeRequest().get();
        final MXMLFileScope fileScope = (MXMLFileScope)fileScopeRequestResult.getScopes()[0];
        
        startProfile(Operation.GET_SYNTAX_TREE);
        
        final IMXMLData mxmlData = getMXMLData();
        
        final Collection<ICompilerProblem> problems = new HashSet<ICompilerProblem>();
        
        // Create an MXMLTreeBuilder to store all the contextual information
        // that we need to build an MXML tree.
        final MXMLTreeBuilder builder =
            new MXMLTreeBuilder(this, getFileSpecificationGetter(),  qname, mxmlData, fileScope, problems);

        // Use the MXMLTreeBuilder to build an MXMLFileNode (the root of an MXML AST)
        // from the MXMLData (the MXML DOM) and the MXMLFileScope.
        final IMXMLFileNode fileNode = builder.build();

        try
        {
            // TODO This belongs in MXMLDocumentNode.
            MXMLDocumentNode documentNode = (MXMLDocumentNode)fileNode.getDocumentNode();
            if (documentNode != null)
            {
                ClassDefinition mainClassDefinition = fileScope.getMainClassDefinition();
                if (mainClassDefinition != null)
                {
                    TypeScope mainClassScope = (TypeScope)mainClassDefinition.getContainedScope();
                    documentNode.setScope(mainClassScope);
                }
            }
            
            // Start CSS semantic analysis. 
            final Function<IMXMLStyleNode, ICSSDocument> parseMXMLStyleNode = new Function<IMXMLStyleNode, ICSSDocument>()
            {
                @Override
                public ICSSDocument apply(IMXMLStyleNode mxmlStyleNode)
                {
                    // This method will trigger the CSS parser to parse the CSS fragment.
                    return mxmlStyleNode.getCSSDocument(problems);
                }
            };
            final Collection<ICSSDocument> cssDocumentList =
                    transform(fileNode.getStyleNodes(), parseMXMLStyleNode);

            // This method will resolve dependencies introduced by the CSS fragment, and add the
            // dependee's to the dependency graph. This is done at the last step in MXML tree 
            // building phase. 
            // - It can't be done in MXML semantic analysis, because MXML code generation doesn't
            //   depend on MXML semantic analysis; 
            // - It can't be done in MXML code generation either, because the "problems" in that phase are 
            //   generated from inside ABCGenerator.
            updateStyleCompilationUnitDependencies(
                    fileNode.getCSSCompilationSession(), 
                    fileScope,
                    cssDocumentList, 
                    problems);
            
            fileNode.getCSSCompilationSession().cssDocuments.addAll(cssDocumentList);
        }
        catch (Exception e)
        {
            //something went wrong, so log it.  
            problems.add(new UnexpectedExceptionProblem(e));
        }
        finally
        {
            stopProfile(Operation.GET_SYNTAX_TREE);
        }

        getProject().addToASTCache(fileNode);
        return new SyntaxTreeRequestResult(fileNode, ImmutableSet.<String>copyOf(fileScope.getSourceDependencies()), fileNode.getIncludeTreeLastModified(), problems);
    }

    @Override
    protected IFileScopeRequestResult handleFileScopeRequest() throws InterruptedException
    {
        startProfile(Operation.GET_FILESCOPE);
        try
        {
            final IMXMLData mxmlData = getMXMLData();
                    
            final MXMLScopeBuilder scopeBuilder = new MXMLScopeBuilder(this, getFileSpecificationGetter(), mxmlData, qname, getAbsoluteFilename());
            MXMLFileScope fileScope = scopeBuilder.build();
            final ImmutableList<OffsetCue> offsetCueList = scopeBuilder.getIncludeHandler().getOffsetCueList();
            final OffsetLookup offsetLookup = new OffsetLookup(offsetCueList);
            fileScope.setOffsetLookup(offsetLookup);
            final Collection<ICompilerProblem> problemCollection = scopeBuilder.getProblems();
            final IFileSpecification rootFileSpec = getRootFileSpecification();

            getProject().getWorkspace().addIncludedFilesToCompilationUnit(this, fileScope.getSourceDependencies());

            return new ASFileScopeRequestResult(getDefinitionPromises(), getDefinitionPriority(), problemCollection, fileScope, rootFileSpec);
        }
        finally
        {
            stopProfile(Operation.GET_FILESCOPE);
        }
    }
    
    @Override
    protected IABCBytesRequestResult handleABCBytesRequest() throws InterruptedException
    {
        // Fulfill other requests before profiling this request.
        final ISyntaxTreeRequestResult syntaxTreeRequestResult = getSyntaxTreeRequest().get();
        final MXMLFileNode fileNode = (MXMLFileNode)syntaxTreeRequestResult.getAST();
        final CompilerProject project = getProject();
        
        startProfile(Operation.GET_ABC_BYTES);
        try
        {
            IABCBytesRequestResult result = CodeGeneratorManager.getCodeGenerator().generate(
                project.getWorkspace().getExecutorService(),
                project.getUseParallelCodeGeneration(),
                getFilenameNoPath(),
                fileNode,
                getProject(),
                isInvisible(),
                getEncodedDebugFiles());
            return result;
        }
        finally
        {
            stopProfile(Operation.GET_ABC_BYTES);
        }
    }

    @Override
    protected ISWFTagsRequestResult handleSWFTagsRequest() throws InterruptedException
    {
        // Fulfill other requests before profiling this request.
        final IABCBytesRequestResult abc = getABCBytesRequest().get();

        startProfile(Operation.GET_SWF_TAGS);

        try
        {
            return new SWFTagsRequestResult(abc.getABCBytes(), qname, abc.getEmbeds());
        }
        finally
        {
            stopProfile(Operation.GET_SWF_TAGS);
        }
    }

    @Override
    protected IOutgoingDependenciesRequestResult handleOutgoingDependenciesRequest () throws InterruptedException
    {
        // Fulfill other requests before profiling this request.
        final ISyntaxTreeRequestResult syntaxTreeRequestResult = getSyntaxTreeRequest().get();
        final MXMLFileNode fileNode = (MXMLFileNode)syntaxTreeRequestResult.getAST();

        startParsingImports(fileNode);

        startProfile(Operation.GET_SEMANTIC_PROBLEMS);
        try
        {
            /* do the codegen now, because we don't discover SDK databinding dependencies
             * until codegen. Long term we probably want to go in this direction anyway,
             * since semantic analysis and codegen may get folded together for other reasons.
             */
            getABCBytesRequest().get(); 
            Collection<ICompilerProblem> problems = new HashSet<ICompilerProblem>();

            updateEmbedCompilationUnitDependencies(fileNode.getEmbedNodes(), problems);
            
            getABCBytesRequest().get();

            // Resolve all references to definitions.
            //fileNode.resolveRefs(problems, getProject());

            return new IOutgoingDependenciesRequestResult()
            {
                @Override
                public ICompilerProblem[] getProblems()
                {
                    return IOutgoingDependenciesRequestResult.NO_PROBLEMS;
                }
            };
        }
        finally
        {
            stopProfile(Operation.GET_SEMANTIC_PROBLEMS);
        }
    }
    
    private IMXMLData getMXMLData()
    {
        // Get the DOM-like MXMLData for the file.
        // If its not already in the Workspace's MXMLDataManager,
        // the MXML file will be parsed.
        final IMXMLDataManager mxmlDataManager = getProject().getWorkspace().getMXMLDataManager();
        final IFileSpecification rootFileSpec = getRootFileSpecification();
        final IMXMLData mxmlData = mxmlDataManager.get(rootFileSpec);
        return mxmlData;
    }
    
    @Override
    public RoyaleProject getProject()
    {
        return (RoyaleProject)super.getProject();
    }
}
