
/*
 * Copyright 2000-2013 JetBrains s.r.o.
 *
 * Licensed 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 com.jetbrains.python.inspections.quickfix;

import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.template.*;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ResolveResult;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.PyRecursiveElementVisitor;
import com.jetbrains.python.psi.PyReferenceExpression;
import com.jetbrains.python.psi.impl.references.PyReferenceImpl;
import com.jetbrains.python.refactoring.PyRefactoringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
 * User : ktisha
 *
 * Quick fix to rename unresolved references
 */
public class PyRenameUnresolvedRefQuickFix implements LocalQuickFix {

  @NotNull
  @Override
  public String getName() {
    return PyBundle.message("QFIX.rename.unresolved.reference");
  }

  @Override
  @NotNull
  public String getFamilyName() {
    return PyBundle.message("QFIX.rename.unresolved.reference");
  }

  @Override
  public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
    final PsiElement element = descriptor.getPsiElement();
    if (!(element instanceof PyReferenceExpression)) {
      return;
    }
    final PyReferenceExpression referenceExpression = (PyReferenceExpression)element;

    ScopeOwner parentScope = ScopeUtil.getScopeOwner(referenceExpression);
    if (parentScope == null) return;

    List<PyReferenceExpression> refs = collectExpressionsToRename(referenceExpression, parentScope);

    LookupElement[] items = collectLookupItems(parentScope);
    final String name = referenceExpression.getReferencedName();

    ReferenceNameExpression refExpr = new ReferenceNameExpression(items, name);
    TemplateBuilderImpl builder = (TemplateBuilderImpl)TemplateBuilderFactory.getInstance().
                                          createTemplateBuilder(parentScope);
    for (PyReferenceExpression expr : refs) {
      if (!expr.equals(referenceExpression)) {
        builder.replaceElement(expr, name, name, false);
      }
      else {
        builder.replaceElement(expr, name, refExpr, true);
      }
    }

    Editor editor = getEditor(project, element.getContainingFile(), parentScope.getTextRange().getStartOffset());
    if (editor != null) {
      Template template = builder.buildInlineTemplate();
      TemplateManager.getInstance(project).startTemplate(editor, template);
    }
  }

  public static boolean isValidReference(final PsiReference reference) {
    if (!(reference instanceof PyReferenceImpl)) return false;
    ResolveResult[] results = ((PyReferenceImpl)reference).multiResolve(true);
    if(results.length == 0) return false;
    for (ResolveResult result : results) {
      if (!result.isValidResult()) return false;
    }
    return true;
  }


  private static List<PyReferenceExpression> collectExpressionsToRename(@NotNull final PyReferenceExpression expression,
                                                                        @NotNull final ScopeOwner parentScope) {

    final List<PyReferenceExpression> result = new ArrayList<PyReferenceExpression>();
    PyRecursiveElementVisitor visitor = new PyRecursiveElementVisitor() {
      @Override
      public void visitPyReferenceExpression(PyReferenceExpression node) {
        if (node.textMatches(expression) && !isValidReference(node.getReference())) {
          result.add(node);
        }
        super.visitPyReferenceExpression(node);
      }
    };

    parentScope.accept(visitor);
    return result;
  }

  @Nullable
  private static Editor getEditor(@NotNull final Project project, @NotNull final PsiFile file, int offset) {
    final VirtualFile virtualFile = file.getVirtualFile();
    return virtualFile != null ? FileEditorManager.getInstance(project).openTextEditor(
      new OpenFileDescriptor(project, virtualFile, offset), true
    ) : null;
  }

  private static LookupElement[] collectLookupItems(@NotNull final ScopeOwner parentScope) {
    Set<LookupElement> items = new LinkedHashSet<LookupElement>();

    final Collection<String> usedNames = PyRefactoringUtil.collectUsedNames(parentScope);
    for (String name : usedNames) {
      if (name != null)
        items.add(LookupElementBuilder.create(name));
    }

    return items.toArray(new LookupElement[items.size()]);
  }

  private class ReferenceNameExpression extends Expression {
    class HammingComparator implements Comparator<LookupElement> {
      @Override
      public int compare(LookupElement lookupItem1, LookupElement lookupItem2) {
        String s1 = lookupItem1.getLookupString();
        String s2 = lookupItem2.getLookupString();
        int diff1 = 0;
        for (int i = 0; i < Math.min(s1.length(), myOldReferenceName.length()); i++) {
          if (s1.charAt(i) != myOldReferenceName.charAt(i)) diff1++;
        }
        int diff2 = 0;
        for (int i = 0; i < Math.min(s2.length(), myOldReferenceName.length()); i++) {
          if (s2.charAt(i) != myOldReferenceName.charAt(i)) diff2++;
        }
        return diff1 - diff2;
      }
    }

    ReferenceNameExpression(LookupElement[] items, String oldReferenceName) {
      myItems = items;
      myOldReferenceName = oldReferenceName;
      Arrays.sort(myItems, new HammingComparator());
    }

    LookupElement[] myItems;
    private final String myOldReferenceName;

    @Override
    public Result calculateResult(ExpressionContext context) {
      if (myItems == null || myItems.length == 0) {
        return new TextResult(myOldReferenceName);
      }
      return new TextResult(myItems[0].getLookupString());
    }

    @Override
    public Result calculateQuickResult(ExpressionContext context) {
      return null;
    }

    @Override
    public LookupElement[] calculateLookupItems(ExpressionContext context) {
      if (myItems == null || myItems.length == 1) return null;
      return myItems;
    }
  }
}
