/*******************************************************************************
 * 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.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.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.ASTListNode;
import org.eclipse.photran.internal.core.parser.ASTModuleNode;
import org.eclipse.photran.internal.core.parser.ASTOnlyNode;
import org.eclipse.photran.internal.core.parser.ASTSeparatedListNode;
import org.eclipse.photran.internal.core.parser.ASTUseStmtNode;
import org.eclipse.photran.internal.core.parser.GenericASTVisitor;
import org.eclipse.photran.internal.core.refactoring.infrastructure.FortranEditorRefactoring;
import org.eclipse.photran.internal.core.reindenter.Reindenter;
import org.eclipse.photran.internal.core.vpg.PhotranTokenRef;
import org.eclipse.photran.internal.core.vpg.PhotranVPG;
/**
 *
 * @author Kurt Hendle
 * @author Jeff Overbey - Externalized strings
 */
public class MinOnlyListRefactoring extends FortranEditorRefactoring
{
    private String moduleName;
    private ASTUseStmtNode useNode = null;
    private List<IFile> filesContainingModule = null;
    private List<Definition> moduleEntityDefs = new ArrayList<Definition>();
    private ArrayList<String> moduleEntityNames = new ArrayList<String>();
    private ArrayList<String> existingOnlyListNames = new ArrayList<String>();
    private ArrayList<String> onlyNamesToKeep = new ArrayList<String>();
    private int numOnlysToKeep = 0;

    public String getModuleName()
    {
        return moduleName;
    }

    /* (non-Javadoc)
     * @see org.eclipse.photran.internal.core.refactoring.infrastructure.AbstractFortranRefactoring#doCheckInitialConditions(org.eclipse.ltk.core.refactoring.RefactoringStatus, org.eclipse.core.runtime.IProgressMonitor)
     * nearly the same as AddOnlyToUseStmtRefactoring.java
     */
    @Override
    protected void doCheckInitialConditions(RefactoringStatus status, IProgressMonitor pm)
        throws PreconditionFailure
    {
        ensureProjectHasRefactoringEnabled(status);

        moduleName = this.selectedRegionInEditor.getText();
        if(moduleName == null || moduleName.equals("")) //$NON-NLS-1$
            fail(Messages.MinOnlyListRefactoring_NoModuleNameSelected);

        findUseStmtNode();
        checkIfModuleExistsInProject();
        getModuleDeclaredEntities(pm);
        readExistingOnlyList();
    }

    //same as AddOnlyToUseStmtRefactoring.java
    private void findUseStmtNode() throws PreconditionFailure
    {
      //get the use statement node in case we need to add to the only list
        Token token = findEnclosingToken();
        if(token == null)
            fail(Messages.MinOnlyListRefactoring_PleaseSelectModuleNameInUSEStatement);

        useNode = token.findNearestAncestor(ASTUseStmtNode.class);
        if(useNode == null)
            fail(Messages.MinOnlyListRefactoring_USEStatementNotFound);
    }

    //same as AddOnlyToUseStmtRefactoring.java
    private void checkIfModuleExistsInProject() throws PreconditionFailure
    {
      //Check to see if the module exists in the project
        filesContainingModule = vpg.findFilesThatExportModule(moduleName);

        if(filesContainingModule.isEmpty() || filesContainingModule == null)
            fail(Messages.bind(Messages.MinOnlyListRefactoring_NoFilesContainModuleNamed, moduleName));
        else if(filesContainingModule.size() > 1)
            filterFileList();

       //check again after the filtering happens
        if(filesContainingModule.isEmpty() || filesContainingModule == null)
            fail(Messages.bind(Messages.MinOnlyListRefactoring_NoFilesContainModuleNamed, moduleName));
    }

    //same method used in CommonVarNamesRefactoring.java
    private void filterFileList() throws PreconditionFailure
    {
        IProject projectInEditor = this.fileInEditor.getProject();  //current project

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

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

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

    //pretty much the same as AddOnlyToUseStmtRefactoring.java
    private void getModuleDeclaredEntities(IProgressMonitor pm) throws PreconditionFailure
    {
        //get module declaration and check if it has declared entities
        PhotranTokenRef moduleTokenRef = vpg.getModuleTokenRef(moduleName);
        if(moduleTokenRef == null)
            fail(Messages.bind(Messages.MinOnlyListRefactoring_ModuleNotFoundWithName, moduleName));

        Token moduleToken = moduleTokenRef.findTokenOrReturnNull();
        if(moduleToken == null){
            fail(Messages.MinOnlyListRefactoring_ModuleTokenNotFound);
        }

        ASTModuleNode moduleNode = moduleToken.findNearestAncestor(ASTModuleNode.class);
        if(moduleNode == null)
            fail(Messages.MinOnlyListRefactoring_ModuleNodeNotFound);

        moduleEntityDefs = moduleNode.getAllPublicDefinitions();
        if(moduleEntityDefs.isEmpty())
        {
            fail(Messages.MinOnlyListRefactoring_ModuleIsEmpty);
        }
        else
        {
            for(int i=0; i<moduleEntityDefs.size(); i++)
                moduleEntityNames.add(moduleEntityDefs.get(i).getCanonicalizedName());
        }
    }

    //nearly the same as AddOnlyToUseStmtRefactoring.java
    @SuppressWarnings("rawtypes")
    private void readExistingOnlyList()
    {
        ASTSeparatedListNode existingOnlys = (ASTSeparatedListNode)useNode.getOnlyList();
        if(existingOnlys != null){
            String name;
            ASTOnlyNode onlyNode = null;
            for(int i=0; i<existingOnlys.size(); i++)
            {
                onlyNode = (ASTOnlyNode)existingOnlys.get(i);
                name = PhotranVPG.canonicalizeIdentifier(onlyNode.getName().getText().trim());
                if(moduleEntityNames.contains(name))
                {
                    if(onlyNode.isRenamed())    //add new name before original
                        existingOnlyListNames.add(onlyNode.getNewName().getText());
                    existingOnlyListNames.add(name);
                }
            }
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.photran.internal.core.refactoring.infrastructure.AbstractFortranRefactoring#doCreateChange(org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    protected void doCreateChange(IProgressMonitor pm) throws CoreException,
        OperationCanceledException
    {
        IFile file = this.fileInEditor;
        IFortranAST ast = vpg.acquirePermanentAST(file);
        if(ast == null) return;

        OnlyTokenVisitor visitor = new OnlyTokenVisitor();
        ast.accept(visitor);

        //actual change takes place here after parsing the AST
        if(numOnlysToKeep == moduleEntityDefs.size())
            removeOnlyList(pm, ast);
        else if(onlyNamesToKeep.isEmpty())
            useNode.removeFromTree(); // remove use node since it is unused
        else
            createAndAddMinOnlyList(pm, ast);

        addChangeFromModifiedAST(fileInEditor, pm);
        vpg.releaseAST(file);
    }

    /* (non-Javadoc)
     * @see org.eclipse.photran.internal.core.refactoring.infrastructure.AbstractFortranRefactoring#doCheckFinalConditions(org.eclipse.ltk.core.refactoring.RefactoringStatus, org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    protected void doCheckFinalConditions(RefactoringStatus status, IProgressMonitor pm)
        throws PreconditionFailure
    {
        //
    }

    @SuppressWarnings("rawtypes")
    private void removeOnlyList(IProgressMonitor pm, IFortranAST ast)
    {
        if(ast == null) return;

        ASTUseStmtNode newStmtNode = (ASTUseStmtNode)parseLiteralStatement("use " + //$NON-NLS-1$
            useNode.getName().getText() + System.getProperty("line.separator")); //$NON-NLS-1$

        ASTListNode body = (ASTListNode)useNode.getParent();
        body.replaceChild(useNode, newStmtNode);
        Reindenter.reindent(newStmtNode, ast);
    }

    @SuppressWarnings("rawtypes")
    private void createAndAddMinOnlyList(IProgressMonitor pm, IFortranAST ast)
    {
        if(ast == null) return;

        String list = ""; //$NON-NLS-1$
        String name;
        int counter = 0;

        while(counter < onlyNamesToKeep.size())
        {
            name = onlyNamesToKeep.get(counter);

            //add the new name for this renamed variable if necessary
            if(!moduleEntityNames.contains(name))
            {
                list += name + " => "; //$NON-NLS-1$
                counter++;
                name = onlyNamesToKeep.get(counter); //update name
            }

            list += name;
            if(counter < onlyNamesToKeep.size()-1)
                list += ", "; //$NON-NLS-1$
            counter++;
        }

        //construct the new USE node and replace the old one in the ast
        ASTUseStmtNode newStmtNode = (ASTUseStmtNode)parseLiteralStatement("use " + //$NON-NLS-1$
            useNode.getName().getText()+", only: " + list + System.getProperty("line.separator")); //$NON-NLS-1$ //$NON-NLS-2$

        ASTListNode body = (ASTListNode)useNode.getParent();
        body.replaceChild(useNode, newStmtNode);
        Reindenter.reindent(newStmtNode, ast);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ltk.core.refactoring.Refactoring#getName()
     */
    @Override
    public String getName()
    {
        return Messages.MinOnlyListRefactoring_Name;
    }

    private final class OnlyTokenVisitor extends GenericASTVisitor
    {
        @Override public void visitToken(Token node)
        {
            String name = PhotranVPG.canonicalizeIdentifier(node.getText());

            if((existingOnlyListNames.contains(name) || moduleEntityNames.contains(name)) &&
                !(node.getParent() instanceof ASTOnlyNode) &&
                !(node.getEnclosingScope() instanceof ASTModuleNode))
            {
                if(!onlyNamesToKeep.contains(name))
                {
                    onlyNamesToKeep.add(name);
                    numOnlysToKeep++;
                }
            }

            //add the new name and original name to keep list
            if(existingOnlyListNames.contains(name) &&
                !onlyNamesToKeep.contains(name) &&
                node.getParent() instanceof ASTOnlyNode)
            {
                ASTOnlyNode thisOnlyNode = (ASTOnlyNode)node.getParent();
                if(thisOnlyNode.isRenamed())
                {
                    onlyNamesToKeep.add(thisOnlyNode.getNewName().getText());
                    onlyNamesToKeep.add(thisOnlyNode.getName().getText());
                    numOnlysToKeep++;
                }
            }
        }
    }

}