/*******************************************************************************
 * Copyright (c) 2009 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.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
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.ltk.core.refactoring.RefactoringStatusContext;
import org.eclipse.photran.core.IFortranAST;
import org.eclipse.photran.internal.core.analysis.binding.Definition;
import org.eclipse.photran.internal.core.lexer.Token;
import org.eclipse.photran.internal.core.parser.ASTCommonBlockNode;
import org.eclipse.photran.internal.core.parser.ASTCommonBlockObjectNode;
import org.eclipse.photran.internal.core.parser.GenericASTVisitor;
import org.eclipse.photran.internal.core.parser.IASTListNode;
import org.eclipse.photran.internal.core.refactoring.infrastructure.FortranEditorRefactoring;
import org.eclipse.photran.internal.core.vpg.PhotranTokenRef;
import org.eclipse.photran.internal.core.vpg.PhotranVPG;

/**
 * Refactoring to make COMMON block variable names consistent between
 * program, modules, subroutines, etc.
 *
 * @author Kurt Hendle
 * @author Ashley Kasza - externalized strings
 */
public class CommonVarNamesRefactoring extends FortranEditorRefactoring
{
    private String commonBlockName = null;
    private HashMap<String, Integer> oldVarNames = new HashMap<String, Integer>();
    private HashMap<Integer, String> newVarNames = new HashMap<Integer, String>();
    private HashMap<Integer, Definition> varDefs = new HashMap<Integer, Definition>();
    private int numCommonVars = 0;

    private ArrayList<String> oldNames = new ArrayList<String>();
    private ArrayList<String> newNames = new ArrayList<String>();

    private ASTCommonBlockNode commonBlockNode = null;
    private List<IFile> filesContainingCommonBlock = null;

    @Override
    public String getName()
    {
        return Messages.CommonVarNamesRefactoring_Name;
    }

    public int getNumCommonVars()
    {
        return numCommonVars;
    }

    public ArrayList<String> getOldVarNames()
    {
        return oldNames;
    }

    public ArrayList<String> getNewVarNames()
    {
        return newNames;
    }

    public void modifyNewName(int varNum, String newName)
    {
        newVarNames.put(varNum, PhotranVPG.canonicalizeIdentifier(newName));
    }

    /* (non-Javadoc) auto-generated */
    @Override
    protected void doCheckInitialConditions(RefactoringStatus status, IProgressMonitor pm)
        throws PreconditionFailure
    {
        ensureProjectHasRefactoringEnabled(status);
        commonBlockName = this.selectedRegionInEditor.getText();

        Token token = findEnclosingToken();

        commonBlockNode = token.findNearestAncestor(ASTCommonBlockNode.class);
        if(commonBlockNode == null)
            fail(Messages.bind(Messages.CommonVarNamesRefactoring_NoCommonBlockFoundWithName, commonBlockName));

        //find all files in the project containing the block
        filesContainingCommonBlock = PhotranVPG.getInstance().findFilesThatUseCommonBlock(commonBlockName);
        if(filesContainingCommonBlock.isEmpty())
            fail(Messages.CommonVarNamesRefactoring_NoFilesFoundContainingCommonBlock); //should never execute
        else
            filterCommonBlockFileList();

        numCommonVars = commonBlockNode.getCommonBlockObjectList().size();

        hashOldAndNewNames();
        getVariableTypes();
    }

    //modified from RenameRefactoring.java
    private Token findEnclosingToken() throws PreconditionFailure
    {
        Token selectedToken = findEnclosingToken(this.astOfFileInEditor, this.selectedRegionInEditor);
        if (selectedToken == null)
            fail(Messages.CommonVarNamesRefactoring_SelectCommonBlockName);
        return selectedToken;
    }

    private void filterCommonBlockFileList() throws PreconditionFailure
    {
        IProject projectInEditor = this.fileInEditor.getProject();  //current project

        if(projectInEditor == null) fail(Messages.CommonVarNamesRefactoring_ProjectDoesNotExist);

        //filter out files not in the project
        int i = 0;
        while(i < filesContainingCommonBlock.size())
        {
            if(filesContainingCommonBlock.get(i) == null
                || !filesContainingCommonBlock.get(i).getProject().equals(projectInEditor))
                filesContainingCommonBlock.remove(i);   //shifts all elements left, don't increment i
            else
                i++;
        }
    }

    private void hashOldAndNewNames()
    {
        //get the old variable names, create new ones
        IASTListNode<ASTCommonBlockObjectNode> commonObjects = commonBlockNode.getCommonBlockObjectList();
        Iterator<ASTCommonBlockObjectNode> iter = commonObjects.iterator();
        int varNameNumber = 0;
        String varName, newName;

        while(iter.hasNext())
        {
            varName = PhotranVPG.canonicalizeIdentifier(iter.next().getVariableName().getText());
            oldNames.add(varName);

            varName = varName.replaceAll("_common", ""); //$NON-NLS-1$ //$NON-NLS-2$
            newName = varName.concat("_common"); //$NON-NLS-1$
            newNames.add(newName);

            oldVarNames.put(varName, varNameNumber);
            //only add new name if there is no existing alias
            if (newVarNames.get(varNameNumber) == null)
                newVarNames.put(varNameNumber, newName);
            varNameNumber++;
        }
    }

    private void getVariableTypes()
    {
        IASTListNode<ASTCommonBlockObjectNode> commonObjects = commonBlockNode.getCommonBlockObjectList();
        int varNameNumber = 0;
        Definition originalDef = null;

        for (ASTCommonBlockObjectNode current : commonObjects)
        {
            originalDef = current.getVariableName().resolveBinding().get(0);
            varDefs.put(varNameNumber, originalDef);

            varNameNumber++;
        }
    }

    private void checkConflictingBindings(ASTCommonBlockNode node, IProgressMonitor pm, RefactoringStatus status)
    {
        Definition defToRename = null;
        Collection<String> newNames = newVarNames.values();
        Collection<PhotranTokenRef> allReferences = null;

        Iterator<ASTCommonBlockObjectNode> blockIter = node.getCommonBlockObjectList().iterator();
        Iterator<String> nameIter = newNames.iterator();

        String oldName, newName;

        //check if each common variable can be renamed
        while(blockIter.hasNext() && nameIter.hasNext())
        {
            defToRename = blockIter.next().getVariableName().resolveBinding().get(0);
            allReferences = defToRename.findAllReferences(true);

            oldName = defToRename.getCanonicalizedName();
            newName = PhotranVPG.canonicalizeIdentifier(nameIter.next());

            if(!oldName.equalsIgnoreCase(newName))
            {
                checkForConflictingBindings(pm,
                    new ConflictingBindingErrorHandler(status),
                    defToRename,
                    allReferences,
                    newName);
            }
        }
    }

    /* auto-generated */
    @Override
    protected void doCreateChange(IProgressMonitor pm) throws CoreException, OperationCanceledException
    {
        //changes made in doCheckFinalConditions
    }

    /* (non-Javadoc) auto-generated */
    @Override
    protected void doCheckFinalConditions(RefactoringStatus status, IProgressMonitor pm)
        throws PreconditionFailure
    {
        assert filesContainingCommonBlock != null;

        try
        {
            for (IFile file : filesContainingCommonBlock)
                makeChangesTo(file, pm, status);
        }
        finally
        {
            vpg.releaseAllASTs();
        }
    }

    private void makeChangesTo(IFile file, IProgressMonitor pm, RefactoringStatus status) throws PreconditionFailure
    {
        IFortranAST ast = vpg.acquirePermanentAST(file);
        if(ast == null) return;

        try
        {
            ConsistencyVisitor replacer = new ConsistencyVisitor(pm, status);
            ast.accept(replacer);

            addChangeFromModifiedAST(file, pm);
        }
        catch(TypeError e)
        {
            fail(e.getMessage());
        }

        vpg.releaseAST(file);
    }

    /** This class is adapted/taken from the code in RenameRefactoring.java */
    private final class ConsistencyVisitor extends GenericASTVisitor
    {
        private IProgressMonitor pm;
        private RefactoringStatus status;
        @SuppressWarnings("unused") private boolean changedAST = false;
        private boolean changeNames = false;
        private HashMap<String, Integer> oldVarNameHash = new HashMap<String, Integer>();
        private HashMap<Integer, Definition> blockVarDefs = new HashMap<Integer, Definition>();

        public ConsistencyVisitor(IProgressMonitor pm, RefactoringStatus status)
        {
            this.pm = pm;
            this.status = status;
        }

        @Override public void visitASTCommonBlockNode(ASTCommonBlockNode node)
        {
            //make sure we aren't looking for null name
            if(node.getName() == null && !commonBlockName.equals("")) //$NON-NLS-1$
                return;

            if((node.getName() == null && commonBlockName.equals("")) || //$NON-NLS-1$
                commonBlockName.equalsIgnoreCase(node.getName().getCommonBlockName().getText()))
            {
                checkConflictingBindings(node, pm, status);
                hashVarNames(node);
            }
        }

        @Override public void visitToken(Token node)
        {
            if(changeNames)
            {
                for (Definition variable : blockVarDefs.values())
                {
                    if (variable.findAllReferences(true).contains(node.getTokenRef())
                        || variable.getTokenRef().equals(node.getTokenRef()))
                    //if(oldVarNameHash.get(node.getText()) != null)
                    {
                        try
                        {
                            changeName(node);
                        }
                        catch(TypeError e)
                        {
                            throw new TypeError(e.getMessage());
                        }
                    }
                }
            }
        }

        private void hashVarNames(ASTCommonBlockNode node)
        {
                //hash old names to new names and indicate name changes should be made
                IASTListNode<ASTCommonBlockObjectNode> objects = node.getCommonBlockObjectList();
                Definition currentDef;
                String currentVarName;
                int varNameNumber = 0;

                for (ASTCommonBlockObjectNode current : objects)
                {
                    currentVarName = current.getVariableName().getText();
                    oldVarNameHash.put(PhotranVPG.canonicalizeIdentifier(currentVarName), varNameNumber);

                    currentDef = current.getVariableName().resolveBinding().get(0);
                    blockVarDefs.put(varNameNumber, currentDef);

                    varNameNumber++;
                }

                changeNames = true;
        }

        private  void changeName(Token node)
        {
            int newNameNumber = oldVarNameHash.get(node.getText());
            Definition origDef = varDefs.get(newNameNumber);
            Definition thisDef = blockVarDefs.get(newNameNumber);

            if(origDef != null && thisDef != null) //skips nodes with null definitions
            {
               if((thisDef.getType().equals(origDef.getType())
                   || (thisDef.isImplicit() || origDef.isImplicit())))
                {
                    String name = newVarNames.get(newNameNumber);
                    node.setText(name);
                    changedAST = true;
                }
                else
                    throw new TypeError(Messages.CommonVarNamesRefactoring_VariableTypesDiffer);
            }
        }
    }

    //borrowed (slightly modified) from RenameRefactoring.java
    private final class ConflictingBindingErrorHandler implements IConflictingBindingCallback
    {
        private final RefactoringStatus status;

        private ConflictingBindingErrorHandler(RefactoringStatus status) { this.status = status; }

        public void addConflictError(List<Conflict> conflictingDef)
        {
            Conflict conflict = conflictingDef.get(0);

            String msg = Messages.bind(Messages.CommonVarNamesRefactoring_NameConflictsWith, conflict.name, vpg.getDefinitionFor(conflict.tokenRef));
            RefactoringStatusContext context = createContext(conflict.tokenRef); // Highlights problematic definition
            status.addError(msg, context);
        }

        public void addConflictWarning(List<Conflict> conflictingDef)
        {
            Conflict conflict = conflictingDef.get(0);

            String msg = Messages.bind(Messages.CommonVarNamesRefactoring_NameMightConflictWithSubprogram, conflict.name);
            RefactoringStatusContext context = createContext(conflict.tokenRef); // Highlights problematic definition
            status.addWarning(msg, context);
        }

        public void addReferenceWillChangeError(String newName, Token reference)
        {
            //
        }
    }

    //custom error class to avoid catching others
    private final class TypeError extends Error
    {
        private static final long serialVersionUID = 1L;

        public TypeError(String message)
        {
            super(message);
        }
    }
}
