/*******************************************************************************
 * Copyright (c) 2010 University of Illinois at Urbana-Champaign and others.
 * 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:
 *    UIUC - Initial API and implementation
 *******************************************************************************/
package org.eclipse.photran.internal.core.refactoring;

import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.photran.internal.core.analysis.binding.Definition;
import org.eclipse.photran.internal.core.analysis.binding.ScopingNode;
import org.eclipse.photran.internal.core.analysis.loops.ASTProperLoopConstructNode;
import org.eclipse.photran.internal.core.analysis.loops.ASTVisitorWithLoops;
import org.eclipse.photran.internal.core.analysis.loops.LoopReplacer;
import org.eclipse.photran.internal.core.lexer.Terminal;
import org.eclipse.photran.internal.core.lexer.Token;
import org.eclipse.photran.internal.core.parser.ASTIntConstNode;
import org.eclipse.photran.internal.core.parser.ASTVisitor;
import org.eclipse.photran.internal.core.parser.IASTListNode;
import org.eclipse.photran.internal.core.parser.IASTNode;
import org.eclipse.photran.internal.core.parser.IExecutionPartConstruct;
import org.eclipse.photran.internal.core.parser.IExpr;
import org.eclipse.photran.internal.core.refactoring.infrastructure.FortranEditorRefactoring;
import org.eclipse.photran.internal.core.reindenter.Reindenter;
import org.eclipse.photran.internal.core.reindenter.Reindenter.Strategy;
import org.eclipse.rephraserengine.core.refactorings.UserInputString;

/**
 * Loop refactoring to take a nested loop and change the data accesses to a tiled form.
 * @author Ashley Kasza
 */
public class TileLoopRefactoring extends FortranEditorRefactoring
{
    private ASTProperLoopConstructNode doLoop;
    private ASTProperLoopConstructNode secondDoLoop;
    private String newFirstIndexVar;
    private String newSecondIndexVar;
    private int tilingSize;
    private int tilingOffset;
    private boolean hasLoopDependency;

    @Override
    protected void doCheckInitialConditions(RefactoringStatus status, IProgressMonitor pm)
        throws PreconditionFailure
    {
        ensureProjectHasRefactoringEnabled(status);

        LoopReplacer.replaceAllLoopsIn(this.astOfFileInEditor.getRoot());
        
        doLoop = getLoopNode(this.astOfFileInEditor, this.selectedRegionInEditor);
        // fail if no do loop was selected
        if (doLoop == null)
        {
            fail(Messages.ReverseLoopRefactoring_SelectDoLoop);
        }
        secondDoLoop = findSecondDoLoop(doLoop);
        if(secondDoLoop == null){
            fail(Messages.ReverseLoopRefactoring_SelectDoLoop);
        }
        //check for nested loops.
        if(findNumberOfLoops() != 1){
            fail(Messages.TileLoopRefactoring_SelectLoopWithOnlyOneNestedLoop);
        }
        newFirstIndexVar = findNewIndexVariableName(doLoop, doLoop.getIndexVariable().getText());
        newSecondIndexVar = findNewIndexVariableName(secondDoLoop, secondDoLoop.getIndexVariable().getText());
        if(newFirstIndexVar == null || newSecondIndexVar == null){
            fail(Messages.TileLoopRefactoring_UnableToCreateNewIndex);
        }
        
        try{
            if(doLoop.getStepInt() != 1 || secondDoLoop.getStepInt() != 1){
                fail(Messages.TileLoopRefactoring_CantTileLoopsWithStep);
            }
        }catch(NumberFormatException e){
            fail(Messages.TileLoopRefactoring_CantTileLoopsWithStep);
        }
        
    }
    
    private ASTProperLoopConstructNode findSecondDoLoop(ASTProperLoopConstructNode firstLoop){
        IASTListNode<IExecutionPartConstruct> firstBody = firstLoop.getBody();
        return firstBody.findFirst(ASTProperLoopConstructNode.class);
    }
    
    private String findNewIndexVariableName(ASTProperLoopConstructNode nodeInScope, String indexVar){
        boolean canUse;
        String newIndexVar = indexVar;
        for (int i = 1; i <= 10; i++)
        {
            canUse = true;
            ScopingNode scope = ScopingNode.getLocalScope(nodeInScope);
            List<Definition> defList = scope.getAllDefinitions();
            for (Definition d : defList)
            {
                if (d != null && d.getCanonicalizedName().equals(newIndexVar.toLowerCase()))
                {
                    newIndexVar = indexVar + Integer.toString(i);
                    canUse = false;
                }
            }
            if (canUse == true)
            {
                return newIndexVar;
            }
        }
        return null;
    }
    
    
    private int findNumberOfLoops(){
        int loopCount = 0;
       IASTListNode<IExecutionPartConstruct> doLoopBody = doLoop.getBody();
       for(int i = 0; i < doLoopBody.size(); i++){
           if(doLoopBody.get(i) instanceof ASTProperLoopConstructNode){
               loopCount++;
           }
       }
       return loopCount;
    }

    @Override
    protected void doCheckFinalConditions(RefactoringStatus status, IProgressMonitor pm)
        throws PreconditionFailure
    {
        // no final conditions
        if(tilingSize <= 0){
            fail(Messages.TileLoopRefactoring_InvalidTileSize);
        }
        if(tilingOffset <0){
            fail(Messages.TileLoopRefactoring_InvalidTilingOffset);
        }
    }
    

    @Override
    protected void doCreateChange(IProgressMonitor pm) throws CoreException,
        OperationCanceledException
    {
        ScopingNode scope = ScopingNode.getLocalScope(doLoop);
        
        hasLoopDependency = false;
        findIndexVariableInHeader(secondDoLoop.getLoopHeader(), doLoop.getIndexVariable().getText());
        
        declareNewLoopVariables(scope);
        
        @SuppressWarnings("unused")
        ASTProperLoopConstructNode node = loopTilingTransformation();
        //parseLiteralDoLoop(node.toString());
        //scope = ScopingNode.getLocalScope(node);
        
        //Reindenter.reindent(loopTilingTransformation(), this.astOfFileInEditor, Strategy.REINDENT_EACH_LINE);
        Reindenter.reindent(scope.getBody(), this.astOfFileInEditor, Strategy.REINDENT_EACH_LINE);

        this.addChangeFromModifiedAST(this.fileInEditor, pm);

        vpg.releaseAST(this.fileInEditor);
    }
    
    private void findIndexVariableInHeader(IASTNode node, final String indexVariable){
        node.accept(new ASTVisitorWithLoops()
        {
            @Override public void visitToken(Token token)
            {
                if(token.getTerminal() == Terminal.T_IDENT && (token.getText()).equalsIgnoreCase(indexVariable)){
                    hasLoopDependency = true;
                }
            }

        });
        //hasLoopDependency = false;
    }
    
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private ASTProperLoopConstructNode loopTilingTransformation(){

        ASTProperLoopConstructNode firstElementLoop = constructNewElementLoop(doLoop, newFirstIndexVar); //inner loop
        ASTProperLoopConstructNode firstTileLoop = createNewTileLoop(doLoop, newFirstIndexVar);
        ASTProperLoopConstructNode secondElementLoop = constructNewElementLoop(secondDoLoop, newSecondIndexVar);
        ASTProperLoopConstructNode secondTileLoop = createNewTileLoop(secondDoLoop, newSecondIndexVar);
        
        if(hasLoopDependency){
            replaceBound(secondTileLoop.getLowerBoundIExpr(), doLoop.getLowerBoundIExpr().toString(), firstTileLoop.getIndexVariable().getText(), true);
            replaceBound(secondTileLoop.getUpperBoundIExpr(), doLoop.getUpperBoundIExpr().toString(), firstTileLoop.getIndexVariable().getText(), false);
        }
        
        IASTListNode body;
        body = secondElementLoop.getBody();
        body.add(secondDoLoop.getBody());
        body = firstElementLoop.getBody();
        body.add(secondElementLoop);
        body = secondTileLoop.getBody();
        body.add(firstElementLoop);
        body = firstTileLoop.getBody();
        body.add(secondTileLoop);
        
        doLoop.replaceWith(firstTileLoop);
        return firstTileLoop;
    }
    
    private void replaceBound(IExpr expr, String replace1, String replace2, boolean isLb){
        if(!(expr instanceof ASTIntConstNode))
        {
            IExpr dummyBound = (IExpr)(expr.clone());
            IExpr dummyBound2 = (IExpr)(expr.clone());
            replaceFirstLoopIndexVariable(dummyBound, doLoop.getIndexVariable().getText(), replace1);
            replaceFirstLoopIndexVariable(dummyBound2, doLoop.getIndexVariable().getText(), replace2);
            if(!(dummyBound.toString().equals(dummyBound2.toString()))){
                String replacementBound;
                if(isLb == true)
                    replacementBound = String.format("max(%s,%s)", dummyBound.toString(), dummyBound2.toString()); //$NON-NLS-1$
                else
                    replacementBound = String.format("min(%s,%s)", dummyBound.toString(), dummyBound2.toString()); //$NON-NLS-1$
                expr.replaceWith(replacementBound);
            }
        }
    }
    
    private void replaceFirstLoopIndexVariable(IASTNode node, final String indexVar, final String replacement)
    {
        node.accept(new ASTVisitor()
        {
            @Override public void visitToken(Token token)
            {
                if(token.getTerminal() == Terminal.T_IDENT && token.getText().equalsIgnoreCase(indexVar)){
                    token.replaceWith(replacement);
                }
            }
        });
    }
    
    @SuppressWarnings("unchecked")
    private void declareNewLoopVariables(ScopingNode scope){
        //ScopingNode scope = ScopingNode.getLocalScope(doLoop);
        IASTListNode<IASTNode> scopeBody = (IASTListNode<IASTNode>)scope.getOrCreateBody();
        String declarationString = "integer :: " + newFirstIndexVar + ", " + newSecondIndexVar; //$NON-NLS-1$ //$NON-NLS-2$
        int insertionIndex = findIndexToInsertTypeDeclaration(scopeBody);
        scopeBody.add(insertionIndex, parseLiteralStatement(declarationString));
    }
    
    private ASTProperLoopConstructNode createNewTileLoop(ASTProperLoopConstructNode inputLoop, String newIndexVar){

        String newLb = getNewBoundsString(inputLoop.getLowerBoundIExpr());
        String newUb = getNewBoundsString(inputLoop.getUpperBoundIExpr());
        String loopHeader = String.format("do %s=%s,%s,%s\nend do\n", newIndexVar, //$NON-NLS-1$
            newLb, newUb,tilingSize); 
        return parseLiteralDoLoop(loopHeader);
    }
    
    private String getNewBoundsString(IExpr expr){
        if(expr instanceof ASTIntConstNode){
            int loopBoundInt = Integer.parseInt(expr.toString());
            int newBound = (int)Math.floor((double)(loopBoundInt-tilingOffset)/tilingSize);
            newBound = (newBound * tilingSize)+tilingOffset;
            return Integer.toString(newBound);
        }else{
            
            //interchangeWithIdentifier = true;
            return String.format("floor(real(%s-%s)/%s)*%s+%s",expr.toString(), Integer.toString(tilingOffset), Integer.toString(tilingSize), //$NON-NLS-1$ 
                Integer.toString(tilingSize), Integer.toString(tilingOffset)); 
        }
        
    }
    
    private ASTProperLoopConstructNode constructNewElementLoop(ASTProperLoopConstructNode inputLoop, String newIndexVar){
        
        String elementLoopLb = String.format("max(%s,%s)", inputLoop.getLowerBoundIExpr().toString(), newIndexVar);//$NON-NLS-1$
        String elementLoopUb = String.format("min(%s,%s+%s)", inputLoop.getUpperBoundIExpr().toString(), newIndexVar, (tilingSize-1));//$NON-NLS-1$
        String elementLoopFull = String.format("do %s=%s,%s\n end do\n", inputLoop.getIndexVariable().getText(), elementLoopLb, elementLoopUb); //$NON-NLS-1$
        ASTProperLoopConstructNode newNode = parseLiteralDoLoop(elementLoopFull);
        return newNode;
    }
    
    
    @UserInputString(label = "Enter tile size ", defaultValueMethod= "getSuggestedTilingSize")
    public void setLoopTilingStepNumber(String input)
    {
        tilingSize = Integer.parseInt(input);
    }
    public String getSuggestedTilingSize()
    {
        return "1"; //$NON-NLS-1$
    }
    @UserInputString(label = "Enter tile offset ", defaultValueMethod = "getSuggestedTilingOffset")
    public void setLoopTilingOffsetNumber(String input)
    {
        tilingOffset = Integer.parseInt(input);
    }
    public String getSuggestedTilingOffset()
    {
        return "1"; //$NON-NLS-1$
    }
    
    @Override
    public String getName()
    {
        return Messages.TileLoopRefactoring_LoopTilingName;
    }
}
