/*
 * 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 com.intellij.refactoring.inline;

import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author yole
 */
public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
  static final ElementPattern ourCatchClausePattern = PlatformPatterns.psiElement(PsiTypeElement.class).withParent(PlatformPatterns.psiElement(PsiParameter.class).withParent(
  PlatformPatterns.psiElement(PsiCatchSection.class)));
  static final ElementPattern ourThrowsClausePattern = PlatformPatterns.psiElement().withParent(PlatformPatterns.psiElement(PsiReferenceList.class).withFirstChild(
    PlatformPatterns.psiElement().withText(PsiKeyword.THROWS)));

  @Override
  public boolean isEnabledOnElement(PsiElement element) {
    return element instanceof PsiMethod || element instanceof PsiClass;
  }

  @Override
  public boolean canInlineElement(final PsiElement element) {
    if (element.getLanguage() != StdLanguages.JAVA) return false;
    if (element instanceof PsiMethod) {
      PsiMethod method = (PsiMethod)element;
      if (method.isConstructor() && !InlineMethodHandler.isChainingConstructor(method)) {
        final PsiClass containingClass = method.getContainingClass();
        if (containingClass == null) return false;
        return findClassInheritors(containingClass);
      }
    }
    if (!(element instanceof PsiClass)) return false;
    if (element instanceof PsiAnonymousClass) return false;
    return findClassInheritors((PsiClass)element);
  }

  private static boolean findClassInheritors(final PsiClass element) {
    final Collection<PsiElement> inheritors = new ArrayList<PsiElement>();
    if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable(){
      @Override
      public void run() {
        ApplicationManager.getApplication().runReadAction(new Runnable() {
          @Override
          public void run() {
            final PsiClass inheritor = ClassInheritorsSearch.search(element).findFirst();
            if (inheritor != null) {
              inheritors.add(inheritor);
            } else {
              final PsiFunctionalExpression functionalExpression = FunctionalExpressionSearch.search(element).findFirst();
              if (functionalExpression != null) {
                inheritors.add(functionalExpression);
              }
            }
          }
        });
      }
    }, "Searching for class \"" + element.getQualifiedName() + "\" inheritors ...", true, element.getProject())) return false;
    return inheritors.isEmpty();
  }

  @Override
  public boolean canInlineElementInEditor(PsiElement element, Editor editor) {
    if (canInlineElement(element)) {
      PsiReference reference = editor != null ? TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset()) : null;
      if (!InlineMethodHandler.isThisReference(reference)) {
        if (element instanceof PsiMethod && reference != null) {
          final PsiElement referenceElement = reference.getElement();
          return referenceElement != null && !PsiTreeUtil.isAncestor(((PsiMethod)element).getContainingClass(), referenceElement, false);
        }
        return true;
      }
    }
    return false;
  }

  @Override
  public void inlineElement(final Project project, final Editor editor, final PsiElement psiElement) {
    final PsiClass psiClass = psiElement instanceof PsiMethod ? ((PsiMethod) psiElement).getContainingClass() : (PsiClass) psiElement;
    PsiCall callToInline = findCallToInline(editor);

    final PsiClassType superType = InlineToAnonymousClassProcessor.getSuperType(psiClass);
    if (superType == null) {
      CommonRefactoringUtil.showErrorHint(project, editor, "java.lang.Object is not found", RefactoringBundle.message("inline.to.anonymous.refactoring"), null);
      return;
    }

    final Ref<String> errorMessage = new Ref<String>();
    if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable(){
      @Override
      public void run() {
        ApplicationManager.getApplication().runReadAction(new Runnable() {
          @Override
          public void run() {
            errorMessage.set(getCannotInlineMessage(psiClass));
          }
        });
      }
    }, "Check if inline is possible...", true, project)) return;
    if (errorMessage.get() != null) {
      CommonRefactoringUtil.showErrorHint(project, editor, errorMessage.get(), RefactoringBundle.message("inline.to.anonymous.refactoring"), null);
      return;
    }

    new InlineToAnonymousClassDialog(project, psiClass, callToInline, canBeInvokedOnReference(callToInline, superType)).show();
  }

  public static boolean canBeInvokedOnReference(PsiCall callToInline, PsiType superType) {
    if (callToInline != null) {
      final PsiElement parent = callToInline.getParent();
      if (parent instanceof PsiExpressionStatement || parent instanceof PsiSynchronizedStatement) {
        return true;
      }
      else if (parent instanceof PsiReferenceExpression) {
        return true;
      }
      else if (parent instanceof PsiExpressionList) {
        final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(parent, PsiMethodCallExpression.class);
        if (methodCallExpression != null) {
          int paramIdx = ArrayUtil.find(methodCallExpression.getArgumentList().getExpressions(), callToInline);
          if (paramIdx != -1) {
            final JavaResolveResult resolveResult = methodCallExpression.resolveMethodGenerics();
            final PsiElement resolvedMethod = resolveResult.getElement();
            if (resolvedMethod instanceof PsiMethod) {
              PsiType paramType;
              final PsiParameter[] parameters = ((PsiMethod)resolvedMethod).getParameterList().getParameters();
              if (paramIdx >= parameters.length) {
                final PsiParameter varargParameter = parameters[parameters.length - 1];
                paramType = varargParameter.getType();
              }
              else {
                paramType = parameters[paramIdx].getType();
              }
              if (paramType instanceof PsiEllipsisType) {
                paramType = ((PsiEllipsisType)paramType).getComponentType();
              }
              paramType = resolveResult.getSubstitutor().substitute(paramType);

              final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)callToInline).getClassOrAnonymousClassReference();
              if (classReference != null) {
                superType = classReference.advancedResolve(false).getSubstitutor().substitute(superType);
                if (TypeConversionUtil.isAssignable(paramType, superType)) {
                  return true;
                }
              }
            }
          }
        }
      }
    }
    return false;
  }


  @Nullable
  public static PsiCall findCallToInline(final Editor editor) {
    PsiCall callToInline = null;
    PsiReference reference = editor != null ? TargetElementUtilBase.findReference(editor) : null;
    if (reference != null) {
      final PsiElement element = reference.getElement();
      if (element instanceof PsiJavaCodeReferenceElement) {
        callToInline = RefactoringUtil.getEnclosingConstructorCall((PsiJavaCodeReferenceElement)element);
      }
    }
    return callToInline;
  }

  @Nullable
  public static String getCannotInlineMessage(final PsiClass psiClass) {
    if (psiClass.isAnnotationType()) {
      return "Annotation types cannot be inlined";
    }
    if (psiClass.isInterface()) {
      return "Interfaces cannot be inlined";
    }
    if (psiClass.isEnum()) {
      return "Enums cannot be inlined";
    }
    if (psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
      return RefactoringBundle.message("inline.to.anonymous.no.abstract");
    }
    if (!psiClass.getManager().isInProject(psiClass)) {
      return "Library classes cannot be inlined";
    }

    PsiClassType[] classTypes = psiClass.getExtendsListTypes();
    for(PsiClassType classType: classTypes) {
      PsiClass superClass = classType.resolve();
      if (superClass == null) {
        return "Class cannot be inlined because its superclass cannot be resolved";
      }
    }

    final PsiClassType[] interfaces = psiClass.getImplementsListTypes();
    if (interfaces.length > 1) {
      return RefactoringBundle.message("inline.to.anonymous.no.multiple.interfaces");
    }
    if (interfaces.length == 1) {
      if (interfaces [0].resolve() == null) {
        return "Class cannot be inlined because an interface implemented by it cannot be resolved";
      }
      final PsiClass superClass = psiClass.getSuperClass();
      if (superClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) {
        PsiClassType interfaceType = interfaces[0];
        if (!isRedundantImplements(superClass, interfaceType)) {
          return RefactoringBundle.message("inline.to.anonymous.no.superclass.and.interface");
        }
      }
    }

    final PsiMethod[] methods = psiClass.getMethods();
    for(PsiMethod method: methods) {
      if (method.isConstructor()) {
        PsiReturnStatement stmt = findReturnStatement(method);
        if (stmt != null) {
          return "Class cannot be inlined because its constructor contains 'return' statements";
        }
      }
      else if (method.findSuperMethods().length == 0) {
        if (!ReferencesSearch.search(method).forEach(new AllowedUsagesProcessor(psiClass))) {
          return "Class cannot be inlined because it has usages of methods not inherited from its superclass or interface";
        }
      }
      if (method.hasModifierProperty(PsiModifier.STATIC)) {
        return "Class cannot be inlined because it has static methods";
      }
    }

    final PsiClass[] innerClasses = psiClass.getInnerClasses();
    for(PsiClass innerClass: innerClasses) {
      PsiModifierList classModifiers = innerClass.getModifierList();
      if (classModifiers.hasModifierProperty(PsiModifier.STATIC)) {
        return "Class cannot be inlined because it has static inner classes";
      }
      if (!ReferencesSearch.search(innerClass).forEach(new AllowedUsagesProcessor(psiClass))) {
        return "Class cannot be inlined because it has usages of its inner classes";
      }
    }

    final PsiField[] fields = psiClass.getFields();
    for(PsiField field: fields) {
      final PsiModifierList fieldModifiers = field.getModifierList();
      if (fieldModifiers != null && fieldModifiers.hasModifierProperty(PsiModifier.STATIC)) {
        if (!fieldModifiers.hasModifierProperty(PsiModifier.FINAL)) {
          return "Class cannot be inlined because it has static non-final fields";
        }
        Object initValue = null;
        final PsiExpression initializer = field.getInitializer();
        if (initializer != null) {
          initValue = JavaPsiFacade.getInstance(psiClass.getProject()).getConstantEvaluationHelper().computeConstantExpression(initializer);
        }
        if (initValue == null) {
          return "Class cannot be inlined because it has static fields with non-constant initializers";
        }
      }
      if (!ReferencesSearch.search(field).forEach(new AllowedUsagesProcessor(psiClass))) {
        return "Class cannot be inlined because it has usages of fields not inherited from its superclass";
      }
    }

    final PsiClassInitializer[] initializers = psiClass.getInitializers();
    for(PsiClassInitializer initializer: initializers) {
      final PsiModifierList modifiers = initializer.getModifierList();
      if (modifiers != null && modifiers.hasModifierProperty(PsiModifier.STATIC)) {
        return "Class cannot be inlined because it has static initializers";
      }
    }

    return getCannotInlineDueToUsagesMessage(psiClass);
  }

  static boolean isRedundantImplements(final PsiClass superClass, final PsiClassType interfaceType) {
    boolean redundantImplements = false;
    PsiClassType[] superClassInterfaces = superClass.getImplementsListTypes();
    for(PsiClassType superClassInterface: superClassInterfaces) {
      if (superClassInterface.equals(interfaceType)) {
        redundantImplements = true;
        break;
      }
    }
    return redundantImplements;
  }

  private static PsiReturnStatement findReturnStatement(final PsiMethod method) {
    final Ref<PsiReturnStatement> stmt = Ref.create(null);
    method.accept(new JavaRecursiveElementWalkingVisitor() {
      @Override public void visitReturnStatement(final PsiReturnStatement statement) {
        super.visitReturnStatement(statement);
        stmt.set(statement);
      }
    });
    return stmt.get();
  }

  @Nullable
  private static String getCannotInlineDueToUsagesMessage(final PsiClass aClass) {
    boolean hasUsages = false;
    for(PsiReference reference : ReferencesSearch.search(aClass)) {
      final PsiElement element = reference.getElement();
      if (element == null) continue;
      if (!PsiTreeUtil.isAncestor(aClass, element, false)) {
        hasUsages = true;
      }
      final PsiElement parentElement = element.getParent();
      if (parentElement != null) {
        final PsiElement grandPa = parentElement.getParent();
        if (grandPa instanceof PsiClassObjectAccessExpression) {
          return "Class cannot be inlined because it has usages of its class literal";
        }
        if (ourCatchClausePattern.accepts(parentElement)) {
          return "Class cannot be inlined because it is used in a 'catch' clause";
        }
      }
      if (ourThrowsClausePattern.accepts(element)) {
        return "Class cannot be inlined because it is used in a 'throws' clause";
      }
      if (parentElement instanceof PsiThisExpression) {
        return "Class cannot be inlined because it is used as a 'this' qualifier";
      }
      if (parentElement instanceof PsiNewExpression) {
        final PsiNewExpression newExpression = (PsiNewExpression)parentElement;
        final PsiMethod[] constructors = aClass.getConstructors();
        if (constructors.length == 0) {
          PsiExpressionList newArgumentList = newExpression.getArgumentList();
          if (newArgumentList != null && newArgumentList.getExpressions().length > 0) {
            return "Class cannot be inlined because a call to its constructor is unresolved";
          }
        }
        else {
          final JavaResolveResult resolveResult = newExpression.resolveMethodGenerics();
          if (!resolveResult.isValidResult()) {
            return "Class cannot be inlined because a call to its constructor is unresolved";
          }
        }
      }
    }
    if (!hasUsages) {
      return RefactoringBundle.message("class.is.never.used");
    }
    return null;
  }

  private static class AllowedUsagesProcessor implements Processor<PsiReference> {
    private final PsiElement myPsiElement;

    public AllowedUsagesProcessor(final PsiElement psiElement) {
      myPsiElement = psiElement;
    }

    @Override
    public boolean process(final PsiReference psiReference) {
      if (PsiTreeUtil.isAncestor(myPsiElement, psiReference.getElement(), false)) {
        return true;
      }
      PsiElement element = psiReference.getElement();
      if (element instanceof PsiReferenceExpression) {
        PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression();
        while (qualifier instanceof PsiParenthesizedExpression) {
          qualifier = ((PsiParenthesizedExpression) qualifier).getExpression();
        }
        if (qualifier instanceof PsiNewExpression) {
          PsiNewExpression newExpr = (PsiNewExpression) qualifier;
          PsiJavaCodeReferenceElement classRef = newExpr.getClassReference();
          if (classRef != null && myPsiElement.equals(classRef.resolve())) {
            return true;
          }
        }
      }
      return false;
    }
  }
}