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

import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.lang.refactoring.InlineHandler;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.inline.InlineOptionsDialog;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
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.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;

import java.util.*;

/**
 * @author ilyas
 */
@SuppressWarnings({"SuspiciousMethodCalls"})
public class GroovyInlineMethodUtil {
  public static final String REFACTORING_NAME = GroovyRefactoringBundle.message("inline.method.title");

  private GroovyInlineMethodUtil() {
  }

  @Nullable
  public static InlineHandler.Settings inlineMethodSettings(GrMethod method, Editor editor, boolean invokedOnReference) {

    final Project project = method.getProject();
    if (method.isConstructor()) {
      String message = GroovyRefactoringBundle.message("refactoring.cannot.be.applied.to.constructors", REFACTORING_NAME);
      showErrorMessage(message, project, editor);
      return InlineHandler.Settings.CANNOT_INLINE_SETTINGS;
    }

    if (invokedOnReference) {
      PsiReference reference = editor != null ? TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset()) : null;
      if (reference == null) return InlineHandler.Settings.CANNOT_INLINE_SETTINGS;

      PsiElement element = reference.getElement();

      if (!(element instanceof GrExpression && element.getParent() instanceof GrCallExpression)) {
        String message = GroovyRefactoringBundle.message("refactoring.is.available.only.for.method.calls", REFACTORING_NAME);
        showErrorMessage(message, project, editor);
        return InlineHandler.Settings.CANNOT_INLINE_SETTINGS;
      }

      GrCallExpression call = (GrCallExpression)element.getParent();

      if (PsiTreeUtil.getParentOfType(element, GrParameter.class) != null) {
        String message = GroovyRefactoringBundle.message("refactoring.is.not.supported.in.parameter.initializers", REFACTORING_NAME);
        showErrorMessage(message, project, editor);
        return InlineHandler.Settings.CANNOT_INLINE_SETTINGS;
      }


      GroovyRefactoringUtil.highlightOccurrences(project, editor, new GrExpression[]{call});
      if (hasBadReturns(method) && !isTailMethodCall(call)) {
        String message = GroovyRefactoringBundle.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow", REFACTORING_NAME);
        showErrorMessage(message, project, editor);
        return InlineHandler.Settings.CANNOT_INLINE_SETTINGS;
      }
    }
    else {
      if (hasBadReturns(method)) {
        String message = GroovyRefactoringBundle.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow", REFACTORING_NAME);
        showErrorMessage(message, project, editor);
        return InlineHandler.Settings.CANNOT_INLINE_SETTINGS;
      }
    }

    if (method.getBlock() == null) {
      String message = method.hasModifierProperty(PsiModifier.ABSTRACT)
                       ? GroovyRefactoringBundle.message("refactoring.cannot.be.applied.to.abstract.methods", REFACTORING_NAME)
                       : GroovyRefactoringBundle.message("refactoring.cannot.be.applied.no.sources.attached", REFACTORING_NAME);
      showErrorMessage(message, project, editor);
      return InlineHandler.Settings.CANNOT_INLINE_SETTINGS;
    }

    return inlineMethodDialogResult(method, project, invokedOnReference);
  }

  /**
   * Checks whether given method call is tail call of other method or closure
   *
   * @param call [tail?] Method call
   * @return
   */
  static boolean isTailMethodCall(GrCallExpression call) {
    GrStatement stmt = call;
    PsiElement parent = call.getParent();

    // return statement
    if (parent instanceof GrReturnStatement) {
      stmt = ((GrReturnStatement) parent);
      parent = parent.getParent();
    }
    // method body result
    if (parent instanceof GrOpenBlock) {
      if (parent.getParent() instanceof GrMethod) {
        GrStatement[] statements = ((GrOpenBlock) parent).getStatements();
        return statements.length > 0 && stmt == statements[statements.length - 1];

      }
    }
    // closure result
    if (parent instanceof GrClosableBlock) {
      GrStatement[] statements = ((GrClosableBlock) parent).getStatements();
      return statements.length > 0 && stmt == statements[statements.length - 1];
    }

    // todo add for inner method block statements
    // todo test me!
    if (stmt instanceof GrReturnStatement) {
      GrMethod method = PsiTreeUtil.getParentOfType(stmt, GrMethod.class);
      if (method != null) {
        Collection<GrStatement> returnStatements = ControlFlowUtils.collectReturns(method.getBlock());
        return returnStatements.contains(stmt) && !hasBadReturns(method);
      }
    }

    return false;
  }

  /**
   * Shows dialog with question to inline
   */
  @Nullable
  private static InlineHandler.Settings inlineMethodDialogResult(GrMethod method, Project project, boolean invokedOnReference) {
    Application application = ApplicationManager.getApplication();
    if (!application.isUnitTestMode()) {
      final InlineMethodDialog dialog = new InlineMethodDialog(project, method, invokedOnReference, checkMethodForRecursion(method));

      dialog.show();
      if (!dialog.isOK()) {
        WindowManager.getInstance().getStatusBar(project).setInfo(GroovyRefactoringBundle.message("press.escape.to.remove.the.highlighting"));
        return InlineHandler.Settings.CANNOT_INLINE_SETTINGS;
      }
      else {
        return new InlineHandler.Settings() {
          @Override
          public boolean isOnlyOneReferenceToInline() {
            return dialog.isInlineThisOnly();
          }
        };
      }
    }
    return new InlineHandler.Settings() {
      @Override
      public boolean isOnlyOneReferenceToInline() {
        return true;
      }
    };

  }

  private static boolean hasBadReturns(GrMethod method) {
    Collection<GrStatement> returnStatements = ControlFlowUtils.collectReturns(method.getBlock());
    GrOpenBlock block = method.getBlock();
    if (block == null || returnStatements.isEmpty()) return false;
    boolean checked = checkTailOpenBlock(block, returnStatements);
    return !(checked && returnStatements.isEmpty());
  }

  public static boolean checkTailIfStatement(GrIfStatement ifStatement, Collection<GrStatement> returnStatements) {
    GrStatement thenBranch = ifStatement.getThenBranch();
    GrStatement elseBranch = ifStatement.getElseBranch();
    if (elseBranch == null) return false;
    boolean tb = false;
    boolean eb = false;
    if (thenBranch instanceof GrReturnStatement) {
      tb = returnStatements.remove(thenBranch);
    } else if (thenBranch instanceof GrBlockStatement) {
      tb = checkTailOpenBlock(((GrBlockStatement) thenBranch).getBlock(), returnStatements);
    }
    if (elseBranch instanceof GrReturnStatement) {
      eb = returnStatements.remove(elseBranch);
    } else if (elseBranch instanceof GrBlockStatement) {
      eb = checkTailOpenBlock(((GrBlockStatement) elseBranch).getBlock(), returnStatements);
    }

    return tb && eb;
  }

  private static boolean checkTailOpenBlock(GrOpenBlock block, Collection<GrStatement> returnStatements) {
    if (block == null) return false;
    GrStatement[] statements = block.getStatements();
    if (statements.length == 0) return false;
    GrStatement last = statements[statements.length - 1];
    if (returnStatements.contains(last)) {
      returnStatements.remove(last);
      return true;
    }
    if (last instanceof GrIfStatement) {
      return checkTailIfStatement(((GrIfStatement) last), returnStatements);
    }
    return false;

  }

  private static void showErrorMessage(String message, final Project project, Editor editor) {
    CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_METHOD);
  }

  static boolean isStaticMethod(@NotNull GrMethod method) {
    return method.hasModifierProperty(PsiModifier.STATIC);
  }

  static boolean areInSameClass(PsiElement element, GrMethod method) {
    PsiElement parent = element;
    while (!(parent == null || parent instanceof PsiClass || parent instanceof PsiFile)) {
      parent = parent.getParent();
    }
    if (parent instanceof PsiClass) {
      PsiClass methodClass = method.getContainingClass();
      return parent == methodClass;
    }
    if (parent instanceof GroovyFile) {
      PsiElement mParent = method.getParent();
      return mParent instanceof GroovyFile && mParent == parent;
    }
    return false;
  }

  public static Collection<ReferenceExpressionInfo> collectReferenceInfo(GrMethod method) {
    ArrayList<ReferenceExpressionInfo> list = new ArrayList<ReferenceExpressionInfo>();
    collectReferenceInfoImpl(list, method, method);
    return list;
  }

  private static void collectReferenceInfoImpl(Collection<ReferenceExpressionInfo> infos, PsiElement elem, GrMethod method) {
    if (elem instanceof GrReferenceExpression) {
      GrReferenceExpression expr = (GrReferenceExpression) elem;
      PsiReference ref = expr.getReference();
      if (ref != null) {
        PsiElement declaration = ref.resolve();
        if (declaration instanceof GrMember) {
          int offsetInMethod = expr.getTextRange().getStartOffset() - method.getTextRange().getStartOffset();
          GrMember member = (GrMember) declaration;
          infos.add(new ReferenceExpressionInfo(expr, offsetInMethod, member, member.getContainingClass()));
        }
      }
    }
    for (PsiElement element : elem.getChildren()) {
      collectReferenceInfoImpl(infos, element, method);
    }

  }

  public static boolean isSimpleReference(GrExpression qualifier) {
    if (!(qualifier instanceof GrReferenceExpression)) return false;
    GrExpression qual = ((GrReferenceExpression) qualifier).getQualifierExpression();
    return qual == null || isSimpleReference(qual);
  }

  static class ReferenceExpressionInfo {
    public final PsiMember declaration;
    public final GrReferenceExpression expression;
    public final int offsetInMethod;
    public final PsiClass containingClass;

    @Nullable
    public String getPresentation() {
      return declaration.getName();
    }

    public boolean isStatic() {
      return declaration.hasModifierProperty(PsiModifier.STATIC);
    }

    public ReferenceExpressionInfo(GrReferenceExpression expression, int offsetInMethod, PsiMember declaration, PsiClass containingClass) {
      this.expression = expression;
      this.offsetInMethod = offsetInMethod;
      this.declaration = declaration;
      this.containingClass = containingClass;
    }
  }


  static void addQualifiersToInnerReferences(GrMethod method, Collection<ReferenceExpressionInfo> infos, @NotNull GrExpression qualifier)
      throws IncorrectOperationException {
    Set<GrReferenceExpression> exprs = new HashSet<GrReferenceExpression>();
    for (ReferenceExpressionInfo info : infos) {
      PsiReference ref = method.findReferenceAt(info.offsetInMethod);
      if (ref != null && ref.getElement() instanceof GrReferenceExpression) {
        GrReferenceExpression refExpr = (GrReferenceExpression) ref.getElement();
        if (refExpr.getQualifierExpression() == null) {
          exprs.add(refExpr);
        }
      }
    }

    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(qualifier.getProject());
    for (GrReferenceExpression expr : exprs) {
      GrExpression qual = factory.createExpressionFromText(qualifier.getText());
      expr.setQualifier(qual);
    }
  }

  private static boolean checkMethodForRecursion(GrMethod method) {
    return checkCalls(method.getBlock(), method);
  }

  private static boolean checkCalls(PsiElement scope, PsiMethod method) {
    if (scope instanceof GrMethodCall) {
      PsiMethod refMethod = ((GrMethodCall)scope).resolveMethod();
      if (method.equals(refMethod)) return true;
    }

    for (PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()) {
      if (checkCalls(child, method)) return true;
    }

    return false;
  }


  static class InlineMethodDialog extends InlineOptionsDialog {
    public static final String REFACTORING_NAME = GroovyRefactoringBundle.message("inline.method.title");
    private final boolean myAllowInlineThisOnly;

    private final PsiMethod myMethod;

    public InlineMethodDialog(Project project,
                              PsiMethod method,
                              boolean invokedOnReference,
                              final boolean allowInlineThisOnly) {
      super(project, true, method);
      myMethod = method;
      myAllowInlineThisOnly = allowInlineThisOnly;
      myInvokedOnReference = invokedOnReference;

      setTitle(REFACTORING_NAME);

      init();
    }

    @Override
    protected String getBorderTitle() {
      return GroovyRefactoringBundle.message("inline.method.border.title");
    }

    @Override
    protected String getNameLabelText() {
      return GroovyRefactoringBundle.message("inline.method.label", GroovyRefactoringUtil.getMethodSignature(myMethod));
    }

    @Override
    protected String getInlineAllText() {
      return myMethod.isWritable()
             ? GroovyRefactoringBundle.message("all.invocations.and.remove.the.method")
             : GroovyRefactoringBundle.message("all.invocations.in.project");
    }

    @Override
    protected String getInlineThisText() {
      return GroovyRefactoringBundle.message("this.invocation.only.and.keep.the.method");
    }

    @Override
    protected boolean isInlineThis() {
      return false;
    }

    @Override
    protected void doAction() {
      if (getOKAction().isEnabled()) {
        close(OK_EXIT_CODE);
      }
    }

    @Override
    protected void doHelpAction() {
      HelpManager.getInstance().invokeHelp(HelpID.INLINE_METHOD);
    }

    @Override
    protected boolean canInlineThisOnly() {
      return myAllowInlineThisOnly;
    }
  }

  /**
   * Inline method call's arguments as its parameters
   *
   * @param call   method call
   * @param method given method
   */
  public static void replaceParametersWithArguments(GrCallExpression call, GrMethod method) throws IncorrectOperationException {
    GrParameter[] parameters = method.getParameters();
    if (parameters.length == 0) return;

    GrArgumentList argumentList = call.getArgumentList();
    if (argumentList == null) {
      setDefaultValuesToParameters(method, null, call);
      return;
    }

    Project project = call.getProject();

    final GroovyResolveResult resolveResult = call.advancedResolve();
    GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, resolveResult.getSubstitutor());

    if (signature == null) {
      return;
    }
    GrClosureSignatureUtil.ArgInfo<PsiElement>[] infos = GrClosureSignatureUtil.mapParametersToArguments(
      signature,
      call.getNamedArguments(),
      call.getExpressionArguments(),
      call.getClosureArguments(),
      call, true, false
    );
    if (infos == null) return;

    for (int i = 0; i < infos.length; i++) {
      GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = infos[i];
      GrParameter parameter = parameters[i];

      final GrExpression arg = inferArg(signature, parameters, parameter, argInfo, project);
      if (arg != null) {
        replaceAllOccurrencesWithExpression(method, call, arg, parameter);
      }
    }
  }

  @Nullable
  private static GrExpression inferArg(GrClosureSignature signature,
                                       GrParameter[] parameters,
                                       GrParameter parameter,
                                       GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo,
                                       Project project) {
    if (argInfo == null) return null;
    List<PsiElement> arguments = argInfo.args;

    if (argInfo.isMultiArg) { //arguments for Map and varArg
      final PsiType type = parameter.getDeclaredType();
      return GroovyRefactoringUtil.generateArgFromMultiArg(signature.getSubstitutor(), arguments, type, project);
    }
    else {  //arguments for simple parameters
      if (arguments.size() == 1) { //arg exists
        PsiElement arg = arguments.iterator().next();
        if (isVararg(parameter, parameters)) {
          if (arg instanceof GrSafeCastExpression) {
            PsiElement expr = ((GrSafeCastExpression)arg).getOperand();
            if (expr instanceof GrListOrMap && !((GrListOrMap)expr).isMap()) {
              return ((GrListOrMap)expr);
            }
          }
        }

        return (GrExpression)arg;
      }
      else { //arg is skipped. Parameter is optional
        return parameter.getInitializerGroovy();
      }
    }
  }

  private static boolean isVararg(GrParameter p, GrParameter[] parameters) {
    return parameters[parameters.length - 1] == p && p.getType() instanceof PsiArrayType;
  }

  /**
   * replaces parameter occurrences in method with its default values (if it's possible)
   *
   * @param method     given method
    * @param nameFilter specified parameter names (which ma have default initializers)
    * @param call
    */
  private static void setDefaultValuesToParameters(GrMethod method, @Nullable Collection<String> nameFilter, GrCallExpression call) throws IncorrectOperationException {
    if (nameFilter == null) {
      nameFilter = new ArrayList<String>();
      for (GrParameter parameter : method.getParameters()) {
        nameFilter.add(parameter.getName());
      }
    }
    GrParameter[] parameters = method.getParameters();
    for (GrParameter parameter : parameters) {
      GrExpression initializer = parameter.getInitializerGroovy();
      if (nameFilter.contains(parameter.getName()) && initializer != null) {
        replaceAllOccurrencesWithExpression(method, call, initializer, parameter);
      }
    }
  }

  private static void replaceAllOccurrencesWithExpression(GrMethod method,
                                                          GrCallExpression call,
                                                          GrExpression oldExpression,
                                                          GrParameter parameter) {
    Collection<PsiReference> refs = ReferencesSearch.search(parameter, new LocalSearchScope(method), false).findAll();

    final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(call.getProject());
    GrExpression expression = elementFactory.createExpressionFromText(oldExpression.getText());


    if (GroovyRefactoringUtil.hasSideEffect(expression) && refs.size() > 1 || !hasUnresolvableWriteAccess(refs, oldExpression)) {
      final String oldName = parameter.getName();
      final String newName = InlineMethodConflictSolver.suggestNewName(oldName, method, call);

      expression = elementFactory.createExpressionFromText(newName);
      final GrOpenBlock body = method.getBlock();
      final GrStatement[] statements = body.getStatements();
      GrStatement anchor = null;
      if (statements.length > 0) {
        anchor = statements[0];
      }
      body.addStatementBefore(elementFactory.createStatementFromText(createVariableDefinitionText(parameter, oldExpression, newName)),
                              anchor);
    }

    for (PsiReference ref : refs) {
      PsiElement element = ref.getElement();
      if (element instanceof GrReferenceExpression) {
        ((GrReferenceExpression)element).replaceWithExpression(expression, true);
      }
    }
  }

  private static String createVariableDefinitionText(GrParameter parameter, GrExpression expression, String varName) {
    StringBuilder buffer = new StringBuilder();
    final PsiModifierList modifierList = parameter.getModifierList();
    buffer.append(modifierList.getText().trim());
    if (buffer.length() > 0) buffer.append(' ');

    final GrTypeElement typeElement = parameter.getTypeElementGroovy();
    if (typeElement != null) {
      buffer.append(typeElement.getText()).append(' ');
    }

    if (buffer.length() == 0) {
      buffer.append("def ");
    }
    buffer.append(varName).append(" = ").append(expression.getText());
    return buffer.toString();
  }

  /**
   * @param refs collection of references to method parameters. It is considered that these references have no qualifiers
   */
  private static boolean containsWriteAccess(Collection<PsiReference> refs) {
    for (PsiReference ref : refs) {
      final PsiElement element = ref.getElement();
      final PsiElement parent = element.getParent();
      if (parent instanceof GrAssignmentExpression && ((GrAssignmentExpression)parent).getLValue() == element) return true;
      if (parent instanceof GrUnaryExpression) return true;
    }
    return false;
  }

  private static boolean hasUnresolvableWriteAccess(Collection<PsiReference> refs, GrExpression expression) {
    if (containsWriteAccess(refs)) {
      if (expression instanceof GrReferenceExpression) {
        final PsiElement resolved = ((GrReferenceExpression)expression).resolve();

        if (resolved instanceof GrVariable && !(resolved instanceof PsiField)) {
          final boolean isFinal = ((GrVariable)resolved).hasModifierProperty(PsiModifier.FINAL);
          if (!isFinal) {
            final PsiReference lastRef =
              Collections.max(ReferencesSearch.search(resolved).findAll(), new Comparator<PsiReference>() {
                @Override
                public int compare(PsiReference o1, PsiReference o2) {
                  return o1.getElement().getTextRange().getStartOffset() - o2.getElement().getTextRange().getStartOffset();
                }
              });
            return lastRef.getElement() == expression;
          }
        }
      }
      return false;
    }

    return true;
  }
}
