/**********************************************************************
 * Copyright (c) 2006 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ptp.pldt.openmp.analysis.ompcfg.factory;
import org.eclipse.ptp.pldt.openmp.analysis.OpenMPError;
import org.eclipse.ptp.pldt.openmp.analysis.OpenMPErrorManager;
import org.eclipse.ptp.pldt.openmp.analysis.PAST.PASTOMPPragma;
import org.eclipse.ptp.pldt.openmp.analysis.ompcfg.OMPCFG;
import org.eclipse.ptp.pldt.openmp.analysis.ompcfg.OMPCFGNode;
import org.eclipse.ptp.pldt.openmp.analysis.ompcfg.OMPDFS;
import org.eclipse.ptp.pldt.openmp.analysis.ompcfg.OMPPragmaNode;

/**
 * Look for common semantic errors
 * 
 * @author pazel
 *
 */
public class PASTSemanticCheck
{
    protected int numErrors_ = 0;
    
    protected PASTSemanticCheck(OMPCFG cfg)
    {
        SemanticDFS dfs = new SemanticDFS(cfg.getRoot());
        dfs.startWalking();
        
    }

    public static boolean checkSemantics(OMPCFG cfg)
    {
        PASTSemanticCheck psc = new PASTSemanticCheck(cfg);
        return psc.getNumErrors()==0 ? true : false;
    }
    
    public int getNumErrors()
    {
        return numErrors_;
    }
    
    private void checkPragmaSemantics(OMPPragmaNode pnode)
    {
        PASTOMPPragma pragma = pnode.getPragma();
        if (pragma==null)  // implicit barrier
            return;
        
        switch(pragma.getOMPType()) {
            // followed by structured region
            case PASTOMPPragma.OmpParallel:
               parallelCheck(pnode);
               break;
            case PASTOMPPragma.OmpSections:
            case PASTOMPPragma.OmpSection:
            case PASTOMPPragma.OmpParallelSections:
            case PASTOMPPragma.OmpSingle:
                break;
            case PASTOMPPragma.OmpMaster:
                masterCheck(pnode);
                break;
            case PASTOMPPragma.OmpCritical:
                break;
            case PASTOMPPragma.OmpOrdered:
                orderedCheck(pnode);
                break;
                
            // Must be followed by FOR
            case PASTOMPPragma.OmpFor:
            case PASTOMPPragma.OmpParallelFor:
                forCheck(pnode);
                break;

            // Stands alone
            case PASTOMPPragma.OmpBarrier:
                barrierCheck(pnode);
                break;
            case PASTOMPPragma.OmpFlush:
            case PASTOMPPragma.OmpThreadPrivate:
                break;
            
            // Followed by expression
            case PASTOMPPragma.OmpAtomic:
                break;
            case PASTOMPPragma.OmpUnknown:
                return;  
        }
        return;
    }
    
    /**
     * parallelCheck - semantic check for Parallel statements
     * @param pnode - OMPPragmaNode
     */
    private void parallelCheck(OMPPragmaNode pnode)
    {
        // A parallel directive dynamically inside another parallel
        // logically etablishes a new team which is composed of only the current thread,
        // unless nested parallelism is enabled.
        OMPPragmaNode parent = pnode.getContextPredecessor();
        while(parent!=null) {
            int pType = parent.getPragma().getOMPType();
            if (pType==PASTOMPPragma.OmpParallel ||
                pType==PASTOMPPragma.OmpParallelFor ||
                pType==PASTOMPPragma.OmpParallelSections) {
                handleProblem(pnode.getPragma(), 
                        "Parallel directive dynamically inside another parallel, establishes single thread context",
                        OpenMPError.WARN);
                numErrors_++;
                break;
            }
            parent = parent.getContextPredecessor();
        }
        return;
    }
    
    /**
     * forCheck - Semantic check for For/parallelFor semantic mistakes
     * @param pnode - OMPPragmaNode (for for/parallelFor)
     */
    private void forCheck(OMPPragmaNode pnode)
    {
        // A for directive is not allowed to nest with another for, sections, 
        // and single directive bound to the same parallel 
        // neither for ritical, ordered, and master regions
        PASTOMPPragma pragma = pnode.getPragma();
        boolean       isParallel = (pragma.getOMPType()==PASTOMPPragma.OmpParallelFor);
        OMPPragmaNode parent = pnode.getContextPredecessor();
        boolean       errorFound=false;
        while(parent!=null) {
            int parentType = parent.getPragma().getOMPType();
            if (!errorFound) { 
               if (parentType==PASTOMPPragma.OmpFor ||
                   parentType==PASTOMPPragma.OmpSections ||
                   parentType==PASTOMPPragma.OmpSingle) {
                 errorFound=true; 
               }
               else if (parentType==PASTOMPPragma.OmpCritical ||
                        parentType==PASTOMPPragma.OmpOrdered  ||
                        parentType==PASTOMPPragma.OmpMaster) {
                   handleProblem(pnode.getPragma(), 
                           "For directive embedded within critical, ordered, or master extents",
                           OpenMPError.ERROR);
                   numErrors_++;
                   errorFound=true;
                   break;
                }
               else if (parentType==PASTOMPPragma.OmpParallelFor ||
                        parentType==PASTOMPPragma.OmpParallelSections) {
                   handleProblem(pnode.getPragma(), 
                           "For directive embedded within another parallel for or parallel sections",
                           OpenMPError.ERROR);
                   numErrors_++;
                   errorFound=true;
                   break;
               }
               else if (isParallel && parentType==PASTOMPPragma.OmpParallel) {
                   handleProblem(pnode.getPragma(), 
                           "Parallel directive dynamically inside another parallel, establishes single thread context",
                           OpenMPError.WARN);
                   numErrors_++;
                   break;                 
               }
            }
            if (errorFound && (parentType==PASTOMPPragma.OmpParallel ||
                               parentType==PASTOMPPragma.OmpParallelFor ||
                               parentType==PASTOMPPragma.OmpParallelSections))
            {
                handleProblem(pnode.getPragma(), 
                        "For directive embedded within another for, sections, or single directive",
                        OpenMPError.ERROR);
                numErrors_++;
                break;
             }
            parent = parent.getContextPredecessor();
        }
        return;
    }
    
    /**
     * barrierCheck - semantic check on barrier statement
     * @param pnode - OMPPragmaNode
     */
    private void barrierCheck(OMPPragmaNode pnode)
    {
        // Barrier directives are not permitted in the dynamic extent of for, ordered, sections, single,
        // master, and critical regions
        OMPPragmaNode parent = pnode.getContextPredecessor();
        while(parent!=null) {
            int pType = parent.getPragma().getOMPType();
            if (pType==PASTOMPPragma.OmpFor || pType==PASTOMPPragma.OmpParallelFor ||
                pType==PASTOMPPragma.OmpOrdered || pType==PASTOMPPragma.OmpSections ||
                pType==PASTOMPPragma.OmpSingle  || pType==PASTOMPPragma.OmpMaster ||
                pType==PASTOMPPragma.OmpCritical) {
                handleProblem(pnode.getPragma(), 
                        "Barrier directive not permitted in region extent of for, ordered, sections, single, master, and critical",
                        OpenMPError.ERROR);
                numErrors_++;
                break;
             }
            parent = parent.getContextPredecessor();
        }
        return;
    }
    
    /**
     * masterCheck - semantic check for use of master directive
     * @param pnode - OMPPragmaNode
     */
    private void masterCheck(OMPPragmaNode pnode)
    {
        // Master directives are not permitted in the dynamic extent of 
        // for, sections, and single
        OMPPragmaNode parent = pnode.getContextPredecessor();
        while(parent!=null) {
            int pType = parent.getPragma().getOMPType();
            if (pType==PASTOMPPragma.OmpFlush || pType==PASTOMPPragma.OmpParallelFor ||
                pType==PASTOMPPragma.OmpSections || pType==PASTOMPPragma.OmpParallelSections ||
                pType==PASTOMPPragma.OmpSingle) {
                handleProblem(pnode.getPragma(), 
                        "Master directive not permitted in dynamic extent of for, sections, or single directives",
                        OpenMPError.ERROR);
                numErrors_++;
                break;
            }
            parent = parent.getContextPredecessor();
        }
        return;
    }
    
    /**
     * orderedCheck - semantic check on ordered directive
     * @param pnode - OMPPragmaNode
     */
    private void orderedCheck(OMPPragmaNode pnode)
    {
        // Ordered directives are not permitted in the dynamic extend of critical regions 
        OMPPragmaNode parent = pnode.getContextPredecessor();
        while(parent!=null) {
            int pType = parent.getPragma().getOMPType();
            if (pType==PASTOMPPragma.OmpCritical) {
                handleProblem(pnode.getPragma(), 
                        "Ordered directive not permitted in dynamic extent of critical region",
                        OpenMPError.ERROR);
                numErrors_++;
                break;
            }
            parent = parent.getContextPredecessor();
        }
        return;
    }
    
    
    /**
     * handleProblem
     * @param description - String
     * @param severity    - int
     */
    private void handleProblem(PASTOMPPragma pragma, String  description, int severity)
    {
        OpenMPError error = new OpenMPError(description, 
                                            pragma.getContainingFilename(),
                                            pragma.getStartingLine(),
                                            severity);
        OpenMPErrorManager.getCurrentErrorManager().addError(error);
        pragma.addProblem(error);  // we really don't need this, but may be useful later
    }

    
    
    private class SemanticDFS extends OMPDFS
    {
        
        public SemanticDFS(OMPCFGNode startNode)
        {
            super(startNode);
        }


        public int visit(OMPCFGNode node)
        {
            if (node instanceof OMPPragmaNode) 
                checkPragmaSemantics((OMPPragmaNode)node);
            return 0;
        }
        
    }

}
