/*
 * Copyright 2000-2009 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.intellij.codeInsight;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.RefactoringChangeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class ChangeContextUtil {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ChangeContextUtil");

  public static final Key<String> ENCODED_KEY = Key.create("ENCODED_KEY");
  public static final Key<PsiClass> THIS_QUALIFIER_CLASS_KEY = Key.create("THIS_QUALIFIER_CLASS_KEY");
  public static final Key<PsiMember> REF_MEMBER_KEY = Key.create("REF_MEMBER_KEY");
  public static final Key<Boolean> CAN_REMOVE_QUALIFIER_KEY = Key.create("CAN_REMOVE_QUALIFIER_KEY");
  public static final Key<PsiClass> REF_CLASS_KEY = Key.create("REF_CLASS_KEY");
  public static final Key<PsiClass> REF_MEMBER_THIS_CLASS_KEY = Key.create("REF_MEMBER_THIS_CLASS_KEY");

  private ChangeContextUtil() {}

  public static void encodeContextInfo(PsiElement scope, boolean includeRefClasses) {
    encodeContextInfo(scope, scope, includeRefClasses, true);
  }

  public static void encodeContextInfo(PsiElement scope, boolean includeRefClasses, boolean canChangeQualifier) {
    encodeContextInfo(scope, scope, includeRefClasses, canChangeQualifier);
  }

  private static void encodeContextInfo(PsiElement scope,
                                        PsiElement topLevelScope,
                                        boolean includeRefClasses,
                                        boolean canChangeQualifier) {
    if (scope instanceof PsiThisExpression){
      scope.putCopyableUserData(ENCODED_KEY, "");

      PsiThisExpression thisExpr = (PsiThisExpression)scope;
      final PsiJavaCodeReferenceElement qualifier = thisExpr.getQualifier();
      if (qualifier == null){
        PsiClass thisClass = RefactoringChangeUtil.getThisClass(thisExpr);
        if (thisClass != null && !(thisClass instanceof PsiAnonymousClass)){
          thisExpr.putCopyableUserData(THIS_QUALIFIER_CLASS_KEY, thisClass);
        }
      }
      else {
        final PsiElement resolved = qualifier.resolve();
        if (resolved instanceof PsiClass && resolved == topLevelScope) {
          thisExpr.putCopyableUserData(THIS_QUALIFIER_CLASS_KEY, (PsiClass)topLevelScope);
        }
      }
    }
    else if (scope instanceof PsiReferenceExpression){
      scope.putCopyableUserData(ENCODED_KEY, "");

      PsiReferenceExpression refExpr = (PsiReferenceExpression)scope;
      PsiExpression qualifier = refExpr.getQualifierExpression();
      if (qualifier == null){
        final JavaResolveResult resolveResult = refExpr.advancedResolve(false);
        final PsiElement refElement = resolveResult.getElement();
        if (refElement != null && !PsiTreeUtil.isAncestor(topLevelScope, refElement, false)){
          if (refElement instanceof PsiClass){
            if (includeRefClasses){
              refExpr.putCopyableUserData(REF_CLASS_KEY, (PsiClass)refElement);
            }
          }
          else if (refElement instanceof PsiMember){
            refExpr.putCopyableUserData(REF_MEMBER_KEY, ( (PsiMember)refElement));
            final PsiElement resolveScope = resolveResult.getCurrentFileResolveScope();
            if (resolveScope instanceof PsiClass && !PsiTreeUtil.isAncestor(topLevelScope, resolveScope, false)) {
              refExpr.putCopyableUserData(REF_MEMBER_THIS_CLASS_KEY, (PsiClass)resolveScope);
            }
          }
        }
      }
      else if (canChangeQualifier) {
        refExpr.putCopyableUserData(CAN_REMOVE_QUALIFIER_KEY, canRemoveQualifier(refExpr) ? Boolean.TRUE : Boolean.FALSE);
      }
    }
    else if (includeRefClasses) {
      PsiReference ref = scope.getReference();
      if (ref != null){
        scope.putCopyableUserData(ENCODED_KEY, "");

        PsiElement refElement = ref.resolve();
        if (refElement instanceof PsiClass && !PsiTreeUtil.isAncestor(topLevelScope, refElement, false)){
          scope.putCopyableUserData(REF_CLASS_KEY, (PsiClass)refElement);
        }
      }
    }

    for(PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()){
      encodeContextInfo(child, topLevelScope, includeRefClasses, canChangeQualifier);
    }
  }

  public static PsiElement decodeContextInfo(@NotNull PsiElement scope,
                                             @Nullable PsiClass thisClass,
                                             @Nullable PsiExpression thisAccessExpr) throws IncorrectOperationException {
    if (scope.getCopyableUserData(ENCODED_KEY) != null) {
      scope.putCopyableUserData(ENCODED_KEY, null);

      if (scope instanceof PsiThisExpression) {
        PsiThisExpression thisExpr = (PsiThisExpression)scope;
        scope = decodeThisExpression(thisExpr, thisClass, thisAccessExpr);
      }
      else if (scope instanceof PsiReferenceExpression) {
        scope = decodeReferenceExpression((PsiReferenceExpression)scope, thisAccessExpr, thisClass);
      }
      else {
        PsiClass refClass = scope.getCopyableUserData(REF_CLASS_KEY);
        scope.putCopyableUserData(REF_CLASS_KEY, null);

        if (refClass != null && refClass.isValid()) {
          PsiReference ref = scope.getReference();
          if (ref != null) {
            final String qualifiedName = refClass.getQualifiedName();
            if (qualifiedName != null) {
              if (JavaPsiFacade.getInstance(refClass.getProject()).findClass(qualifiedName, scope.getResolveScope()) != null) {
                scope = ref.bindToElement(refClass);
              }
            }
          }
        }
      }
    }

    if (scope instanceof PsiClass) {
      if (thisAccessExpr != null) {
        thisAccessExpr = (PsiExpression)qualifyThis(thisAccessExpr, thisClass);
      }
    }

    PsiElement child = scope.getFirstChild();
    while (child != null) {
      child = decodeContextInfo(child, thisClass, thisAccessExpr).getNextSibling();
    }

    return scope;
  }

  private static PsiElement decodeThisExpression(PsiThisExpression thisExpr,
                                                 PsiClass thisClass,
                                                 PsiExpression thisAccessExpr) throws IncorrectOperationException {
    final PsiJavaCodeReferenceElement qualifier = thisExpr.getQualifier();
    PsiClass encodedQualifierClass = thisExpr.getCopyableUserData(THIS_QUALIFIER_CLASS_KEY);
    thisExpr.putCopyableUserData(THIS_QUALIFIER_CLASS_KEY, null);
    if (qualifier == null){
      if (encodedQualifierClass != null && encodedQualifierClass.isValid()){
        if (encodedQualifierClass.equals(thisClass) && thisAccessExpr != null && thisAccessExpr.isValid()){
          return thisExpr.replace(thisAccessExpr);
        }
      }
    }
    else {
      PsiClass qualifierClass = (PsiClass)qualifier.resolve();
      if (encodedQualifierClass == qualifierClass && thisClass != null) {
        qualifier.bindToElement(thisClass);
      }
      else {
        if (qualifierClass != null) {
          if (qualifierClass.equals(thisClass) && thisAccessExpr != null && thisAccessExpr.isValid()) {
            return thisExpr.replace(thisAccessExpr);
          }
        }
      }
    }
    return thisExpr;
  }

  private static PsiReferenceExpression decodeReferenceExpression(@NotNull PsiReferenceExpression refExpr,
                                                                  PsiExpression thisAccessExpr,
                                                                  PsiClass thisClass) throws IncorrectOperationException {
    PsiManager manager = refExpr.getManager();
    PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();

    PsiExpression qualifier = refExpr.getQualifierExpression();
    if (qualifier == null){
      PsiMember refMember = refExpr.getCopyableUserData(REF_MEMBER_KEY);
      refExpr.putCopyableUserData(REF_MEMBER_KEY, null);

      if (refMember != null && refMember.isValid()){
        PsiClass containingClass = refMember.getContainingClass();
        if (refMember.hasModifierProperty(PsiModifier.STATIC)){
          PsiElement refElement = refExpr.resolve();
          if (!manager.areElementsEquivalent(refMember, refElement)){
            refExpr.setQualifierExpression(factory.createReferenceExpression(containingClass));
          }
        }
        else {
          final PsiClass realParentClass = refExpr.getCopyableUserData(REF_MEMBER_THIS_CLASS_KEY);
          refExpr.putCopyableUserData(REF_MEMBER_THIS_CLASS_KEY, null);
          if (thisAccessExpr != null && thisClass != null && realParentClass != null &&
              InheritanceUtil.isInheritorOrSelf(thisClass, realParentClass, true)) {
            boolean needQualifier = true;
            PsiElement refElement = refExpr.resolve();
            if (refMember.equals(refElement) ||
                (refElement instanceof PsiMethod && refMember instanceof PsiMethod && ArrayUtil.find(((PsiMethod)refElement).findSuperMethods(), refMember) > -1)){
              if (thisAccessExpr instanceof PsiThisExpression && ((PsiThisExpression)thisAccessExpr).getQualifier() == null) {
                //Trivial qualifier
                needQualifier = false;
              }
              else {
                final PsiClass currentClass = findThisClass(refExpr, refMember);
                if (thisAccessExpr instanceof PsiThisExpression){
                  PsiJavaCodeReferenceElement thisQualifier = ((PsiThisExpression)thisAccessExpr).getQualifier();
                  PsiClass thisExprClass = thisQualifier != null
                                           ? (PsiClass)thisQualifier.resolve()
                                           : RefactoringChangeUtil.getThisClass(refExpr);
                  if (currentClass.equals(thisExprClass) || thisExprClass.isInheritor(realParentClass, true)){ // qualifier is not necessary
                    needQualifier = false;
                  }
                }
              }
            }

            if (needQualifier){
              refExpr.setQualifierExpression(thisAccessExpr);
            }
          }
          else if (thisClass != null && realParentClass != null && PsiTreeUtil.isAncestor(realParentClass, thisClass, true)) {
            PsiElement refElement = refExpr.resolve();
            if (refElement != null && !manager.areElementsEquivalent(refMember, refElement)) {
              refExpr = RefactoringChangeUtil.qualifyReference(refExpr, refMember, null);
            }
          }
        }
      }
      else {
        PsiClass refClass = refExpr.getCopyableUserData(REF_CLASS_KEY);
        refExpr.putCopyableUserData(REF_CLASS_KEY, null);
        if (refClass != null && refClass.isValid()){
          refExpr = (PsiReferenceExpression)refExpr.bindToElement(refClass);
        }
      }
    }
    else{
      Boolean couldRemove = refExpr.getCopyableUserData(CAN_REMOVE_QUALIFIER_KEY);
      refExpr.putCopyableUserData(CAN_REMOVE_QUALIFIER_KEY, null);

      if (couldRemove == Boolean.FALSE && canRemoveQualifier(refExpr)){
        PsiReferenceExpression newRefExpr = (PsiReferenceExpression)factory.createExpressionFromText(
          refExpr.getReferenceName(), null);
        refExpr = (PsiReferenceExpression)refExpr.replace(newRefExpr);
      }
    }
    return refExpr;
  }

  private static PsiClass findThisClass(PsiReferenceExpression refExpr, PsiMember refMember) {
    LOG.assertTrue(refExpr.getQualifierExpression() == null);
    final PsiClass refMemberClass = refMember.getContainingClass();
    if (refMemberClass == null) return null;
    PsiElement parent = refExpr.getContext();
    while(parent != null){
      if (parent instanceof PsiClass){
        if (parent.equals(refMemberClass) || ((PsiClass)parent).isInheritor(refMemberClass, true)){
          return (PsiClass)parent;
        }
      }
      parent = parent.getContext();
    }

    return refMemberClass;
  }

  public static boolean canRemoveQualifier(PsiReferenceExpression refExpr) {
    try{
      PsiExpression qualifier = refExpr.getQualifierExpression();
      if (!(qualifier instanceof PsiReferenceExpression)) return false;
      if (refExpr.getTypeParameters().length > 0) return false;
      PsiElement qualifierRefElement = ((PsiReferenceExpression)qualifier).resolve();
      if (!(qualifierRefElement instanceof PsiClass)) return false;
      PsiElement refElement = refExpr.resolve();
      if (refElement == null) return false;
      PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory();
      if (refExpr.getParent() instanceof PsiMethodCallExpression){
        PsiMethodCallExpression methodCall = (PsiMethodCallExpression)refExpr.getParent();
        PsiMethodCallExpression newMethodCall = (PsiMethodCallExpression)factory.createExpressionFromText(
          refExpr.getReferenceName() + "()", refExpr);
        newMethodCall.getArgumentList().replace(methodCall.getArgumentList());
        PsiElement newRefElement = newMethodCall.getMethodExpression().resolve();
        return refElement.equals(newRefElement);
      }
      else if (refExpr instanceof PsiMethodReferenceExpression) {
        return false;
      }
      else {
        PsiReferenceExpression newRefExpr = (PsiReferenceExpression)factory.createExpressionFromText(
          refExpr.getReferenceName(), refExpr);
        PsiElement newRefElement = newRefExpr.resolve();
        return refElement.equals(newRefElement);
      }
    }
    catch(IncorrectOperationException e){
      LOG.error(e);
      return false;
    }
  }

  private static PsiElement qualifyThis(PsiElement scope, PsiClass thisClass) throws IncorrectOperationException {
    if (scope instanceof PsiThisExpression){
      PsiThisExpression thisExpr = (PsiThisExpression)scope;
      if (thisExpr.getQualifier() == null){
        if (thisClass instanceof PsiAnonymousClass) return null;
        PsiThisExpression qualifiedThis = RefactoringChangeUtil.createThisExpression(thisClass.getManager(), thisClass);
        if (thisExpr.getParent() != null) {
          return thisExpr.replace(qualifiedThis);
        } else {
          return qualifiedThis;
        }
      }
    }
    else if (!(scope instanceof PsiClass)){
      for(PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()){
        if (qualifyThis(child, thisClass) == null) return null;
      }
    }
    return scope;
  }

  public static PsiClass getThisClass(PsiElement element) {
    return PsiTreeUtil.getParentOfType(element, PsiClass.class);
  }

  public static void clearContextInfo(PsiElement scope) {
    scope.putCopyableUserData(THIS_QUALIFIER_CLASS_KEY, null);
    scope.putCopyableUserData(REF_MEMBER_KEY, null);
    scope.putCopyableUserData(CAN_REMOVE_QUALIFIER_KEY, null);
    for(PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()){
      clearContextInfo(child);
    }
  }
}
