/*
 * Copyright 2000-2014 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 org.jetbrains.plugins.groovy.refactoring.move;

import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.moveMembers.MoveMemberHandler;
import com.intellij.refactoring.move.moveMembers.MoveMembersOptions;
import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor;
import com.intellij.refactoring.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstantList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil;

import java.util.*;

/**
 * @author Maxim.Medvedev
 */
public class MoveGroovyMemberHandler implements MoveMemberHandler {
  @Override
  public boolean changeExternalUsage(@NotNull MoveMembersOptions options, @NotNull MoveMembersProcessor.MoveMembersUsageInfo usage) {
    final PsiElement element = usage.getElement();
    if (element == null || !element.isValid()) return true;

    if (usage.reference instanceof GrReferenceExpression) {
      GrReferenceExpression refExpr = (GrReferenceExpression)usage.reference;
      GrExpression qualifier = refExpr.getQualifierExpression();
      if (qualifier != null) {
        if (usage.qualifierClass != null) {
          changeQualifier(refExpr, usage.qualifierClass, usage.member);
        }
        else {
          refExpr.setQualifier(null);
        }
      }
      else { // no qualifier
        if (usage.qualifierClass != null) {
          changeQualifier(refExpr, usage.qualifierClass, usage.member);
        }
      }
      return true;
    }
    return false;
  }

  @Override
  @NotNull
  public PsiMember doMove(@NotNull MoveMembersOptions options, @NotNull PsiMember member, PsiElement anchor, @NotNull PsiClass targetClass) {
    GroovyChangeContextUtil.encodeContextInfo(member);

    final PsiDocComment docComment;
    if (member instanceof PsiDocCommentOwner) {
      docComment = ((PsiDocCommentOwner)member).getDocComment();
    }
    else {
      docComment = null;
    }

    PsiMember moved;
    if (options.makeEnumConstant() &&
        member instanceof GrVariable &&
        EnumConstantsUtil.isSuitableForEnumConstant(((PsiVariable)member).getType(), targetClass)) {
      final GrEnumConstant prototype = createEnumConstant(member.getName(), ((GrVariable)member).getInitializerGroovy(), member.getProject());
      moved = (PsiMember)addEnumConstant(targetClass, prototype, anchor);
      member.delete();
    }
    else if (member instanceof GrEnumConstant) {
      moved = (PsiMember)addEnumConstant(targetClass, (GrEnumConstant)member, null);
    }
    else if (member instanceof GrField) {
      if (anchor != null) anchor = anchor.getParent();

      final GrVariableDeclaration parent = (GrVariableDeclaration)member.getParent();
      GrVariableDeclaration movedDeclaration = (GrVariableDeclaration)targetClass.addAfter(parent, anchor);

      int number = ArrayUtil.find(parent.getMembers(), member);
      final GrMember[] members = movedDeclaration.getMembers();
      for (int i = 0; i < number; i++) {
        members[i].delete();
      }
      for (int i = number + 1; i < members.length; i++) {
        members[i].delete();
      }

      if (member.getContainingClass().isInterface() && !targetClass.isInterface()) {
        //might need to make modifiers explicit, see IDEADEV-11416
        final PsiModifierList list = movedDeclaration.getModifierList();
        VisibilityUtil.setVisibility(list, VisibilityUtil.getVisibilityModifier(member.getModifierList()));
        list.setModifierProperty(PsiModifier.STATIC, member.hasModifierProperty(PsiModifier.STATIC));
        list.setModifierProperty(PsiModifier.FINAL, member.hasModifierProperty(PsiModifier.FINAL));
      }

      moved = movedDeclaration.getMembers()[0];
    }
    else if (member instanceof GrMethod) {
      moved = (PsiMember)targetClass.addAfter(member, anchor);
      if (member.getContainingClass().isInterface() && !targetClass.isInterface()) {
        //might need to make modifiers explicit, see IDEADEV-11416
        final PsiModifierList list = moved.getModifierList();
        assert list != null;
        list.setModifierProperty(PsiModifier.STATIC, member.hasModifierProperty(PsiModifier.STATIC));
        list.setModifierProperty(PsiModifier.FINAL, member.hasModifierProperty(PsiModifier.FINAL));
        VisibilityUtil.setVisibility(list, VisibilityUtil.getVisibilityModifier(member.getModifierList()));
      }

    }
    else {
      moved = (PsiMember)targetClass.addAfter(member, anchor);
    }

    if (docComment != null) {
      PsiElement insertedDocComment = targetClass.addBefore(docComment, moved);
      PsiElement prevSibling = insertedDocComment.getPrevSibling();
      addLineFeedIfNeeded(prevSibling);
      docComment.delete();
    }
    member.delete();
    return moved;
  }

  private static void addLineFeedIfNeeded(PsiElement prevSibling) {
    if (prevSibling == null) return;
    ASTNode node = prevSibling.getNode();
    IElementType type = node.getElementType();

    if (type == GroovyTokenTypes.mNLS) {
      String text = prevSibling.getText();
      int lfCount = StringUtil.countChars(text, '\n');
      if (lfCount < 2) {
        ASTNode parent = node.getTreeParent();
        parent.addLeaf(GroovyTokenTypes.mNLS, text + "\n ", node);
        parent.removeChild(node);
      }
    }
    else {
      node.getTreeParent().addLeaf(GroovyTokenTypes.mNLS, "\n\n ", node.getTreeNext());
    }
  }

  @Override
  public void decodeContextInfo(@NotNull PsiElement scope) {
    GroovyChangeContextUtil.decodeContextInfo(scope, null, null);
  }

  private static void changeQualifier(GrReferenceExpression refExpr, PsiClass aClass, PsiMember member) throws IncorrectOperationException {
    if (hasOnDemandStaticImport(refExpr, aClass)) {
      refExpr.setQualifier(null);
    }
    else if (!hasStaticImport(refExpr, member)) {
      GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(refExpr.getProject());

      refExpr.setQualifier(factory.createReferenceExpressionFromText(aClass.getName()));
      ((GrReferenceExpression)refExpr.getQualifierExpression()).bindToElement(aClass);
    }
  }

  private static boolean hasStaticImport(GrReferenceExpression refExpr, PsiMember member) {
    if (!(refExpr.getContainingFile() instanceof GroovyFile)) return false;

    final GrImportStatement[] imports = ((GroovyFile)refExpr.getContainingFile()).getImportStatements();
    for (GrImportStatement stmt : imports) {
      if (!stmt.isOnDemand() && stmt.resolveTargetClass() == member.getContainingClass() &&
          Comparing.strEqual(stmt.getImportReference().getReferenceName(), member.getName())) {
        return true;
      }
    }
    return false;
  }

  private static boolean hasOnDemandStaticImport(final PsiElement element, final PsiClass aClass) {
    if (element.getContainingFile() instanceof GroovyFile) {
      final GrImportStatement[] importStatements = ((GroovyFile)element.getContainingFile()).getImportStatements();
      for (GrImportStatement stmt : importStatements) {
        final GrCodeReferenceElement ref = stmt.getImportReference();
        if (ref != null && stmt.isStatic() && stmt.isOnDemand() && ref.resolve() == aClass) {
          return true;
        }
      }
    }
    return false;
  }

  @Override
  @Nullable
  public PsiElement getAnchor(@NotNull final PsiMember member, @NotNull final PsiClass targetClass, Set<PsiMember> membersToMove) {
    if (member instanceof GrField && member.hasModifierProperty(PsiModifier.STATIC)) {
      final List<PsiField> referencedFields = new ArrayList<PsiField>();
      final GrExpression psiExpression = ((GrField)member).getInitializerGroovy();
      if (psiExpression != null) {
        psiExpression.accept(new GroovyRecursiveElementVisitor() {
          @Override
          public void visitReferenceExpression(final GrReferenceExpression expression) {
            super.visitReferenceExpression(expression);
            final PsiElement psiElement = expression.resolve();
            if (psiElement instanceof GrField) {
              final GrField grField = (GrField)psiElement;
              if (grField.getContainingClass() == targetClass && !referencedFields.contains(grField)) {
                referencedFields.add(grField);
              }
            }
          }
        });
      }
      if (!referencedFields.isEmpty()) {
        Collections.sort(referencedFields, new Comparator<PsiField>() {
          @Override
          public int compare(final PsiField o1, final PsiField o2) {
            return -PsiUtilCore.compareElementsByPosition(o1, o2);
          }
        });
        return referencedFields.get(0);
      }
    }
    return null;
  }

  private static GrEnumConstant createEnumConstant(String constantName, GrExpression initializerExpr, Project project)
    throws IncorrectOperationException {
    final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(project);
    final String enumConstantText = initializerExpr != null ? constantName + "(" + initializerExpr.getText() + ")" : constantName;
    return elementFactory.createEnumConstantFromText(enumConstantText);
  }

  private static PsiElement addEnumConstant(PsiClass targetClass, GrEnumConstant constant, @Nullable PsiElement anchor) {
    if (targetClass instanceof GrEnumTypeDefinition) {
      final GrEnumTypeDefinition enumeration = (GrEnumTypeDefinition)targetClass;
      final GrEnumConstantList constantList = enumeration.getEnumConstantList();
      if (constantList != null) {
        ASTNode node = constantList.getNode();
        node.addLeaf(GroovyTokenTypes.mCOMMA, ",", node.getFirstChildNode());
        return constantList.addBefore(constant, constantList.getFirstChild());
      }
      else {
        final PsiElement parent = constant.getParent();
        assert parent instanceof GrEnumConstantList;
        final GrEnumConstantList constListCopy = ((GrEnumConstantList)targetClass.add(parent));
        return constListCopy.getEnumConstants()[0];
      }
    }
    return (anchor != null ? targetClass.addAfter(constant, anchor) : targetClass.add(constant));
  }

  @Override
  public MoveMembersProcessor.MoveMembersUsageInfo getUsage(@NotNull PsiMember member,
                                                            @NotNull PsiReference psiReference,
                                                            @NotNull Set<PsiMember> membersToMove,
                                                            @NotNull PsiClass targetClass) {
    PsiElement ref = psiReference.getElement();
    if (ref instanceof GrReferenceExpression) {
      GrReferenceExpression refExpr = (GrReferenceExpression)ref;
      GrExpression qualifier = refExpr.getQualifier();
      if (RefactoringHierarchyUtil.willBeInTargetClass(refExpr, membersToMove, targetClass, true)) {
        // both member and the reference to it will be in target class
        if (!RefactoringUtil.isInMovedElement(refExpr, membersToMove)) {
          if (qualifier != null) {
            return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, null, qualifier, psiReference);  // remove qualifier
          }
        }
        else if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(member.getContainingClass())) {
          return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, null, qualifier, psiReference);  // change qualifier
        }
      }
      else {
        // member in target class, the reference will be outside target class
        if (qualifier == null) {
          return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, targetClass, refExpr, psiReference); // add qualifier
        }
        else {
          return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, targetClass, qualifier, psiReference); // change qualifier
        }
      }
    }
    return null;
  }

  @Override
  public void checkConflictsOnUsage(@NotNull MoveMembersProcessor.MoveMembersUsageInfo usageInfo,
                                    @Nullable String newVisibility,
                                    @Nullable PsiModifierList modifierListCopy,
                                    @NotNull PsiClass targetClass,
                                    @NotNull Set<PsiMember> membersToMove,
                                    @NotNull MultiMap<PsiElement, String> conflicts) {
    final PsiElement element = usageInfo.getElement();
    if (element == null) return;

    final PsiMember member = usageInfo.member;
    if (element instanceof GrReferenceExpression) {
      GrExpression qualifier = ((GrReferenceExpression)element).getQualifier();
      PsiClass accessObjectClass = null;
      if (qualifier != null) {
        accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement();
      }

      if (!JavaResolveUtil.isAccessible(member, targetClass, modifierListCopy, element, accessObjectClass, null)) {
        String visibility = newVisibility != null ? newVisibility : VisibilityUtil.getVisibilityStringToDisplay(member);
        String message = RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2",
                                                   RefactoringUIUtil.getDescription(member, false),
                                                   visibility,
                                                   RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true));
        conflicts.putValue(member, CommonRefactoringUtil.capitalize(message));
      }
    }
  }

  @Override
  public void checkConflictsOnMember(@NotNull PsiMember member,
                                     @Nullable String newVisibility,
                                     @Nullable PsiModifierList modifierListCopy,
                                     @NotNull PsiClass targetClass,
                                     @NotNull Set<PsiMember> membersToMove,
                                     @NotNull MultiMap<PsiElement, String> conflicts) {
  }
}
