/*
 * 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 org.jetbrains.plugins.groovy.intentions.declaration;

import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.codeInsight.template.TemplateEditingAdapter;
import com.intellij.codeInsight.template.TemplateManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.intentions.base.Intention;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
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.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.template.expressions.ChooseTypeExpression;

import java.util.ArrayList;

/**
 * @author Max Medvedev
 */
public class GrSetStrongTypeIntention extends Intention {

  private static final Logger LOG = Logger.getInstance(GrSetStrongTypeIntention.class);

  @Override
  protected void processIntention(@NotNull PsiElement element, Project project, final Editor editor) throws IncorrectOperationException {
    PsiElement parent = element.getParent();

    PsiElement elementToBuildTemplate;
    GrVariable[] variables;
    if (parent instanceof GrVariable && parent.getParent() instanceof GrVariableDeclaration) {
      variables = ((GrVariableDeclaration)parent.getParent()).getVariables();
      elementToBuildTemplate = parent.getParent();
    }
    else if (parent instanceof GrVariable && parent.getParent() instanceof GrForInClause) {
      variables = new GrVariable[]{(GrVariable)parent};
      elementToBuildTemplate = parent.getParent().getParent();
    }
    else if (parent instanceof GrVariableDeclaration) {
      variables = ((GrVariableDeclaration)parent).getVariables();
      elementToBuildTemplate = parent;
    }
    else if (parent instanceof GrParameter && parent.getParent() instanceof GrParameterList) {
      variables = new GrVariable[]{(GrVariable)parent};
      elementToBuildTemplate = parent.getParent().getParent();
    }
    else if (parent instanceof GrVariable) {
      variables = new GrVariable[]{((GrVariable)parent)};
      elementToBuildTemplate = parent;
    }
    else {
      return;
    }

    ArrayList<TypeConstraint> types = new ArrayList<TypeConstraint>();

    if (parent.getParent() instanceof GrForInClause) {
      types.add(SupertypeConstraint.create(PsiUtil.extractIteratedType((GrForInClause)parent.getParent())));
    }
    else {
      for (GrVariable variable : variables) {
        GrExpression initializer = variable.getInitializerGroovy();
        if (initializer != null) {
          PsiType type = initializer.getType();
          if (type != null) {
            types.add(SupertypeConstraint.create(type));
          }
        }
        if (variable instanceof GrParameter) {
          final PsiParameter parameter = (PsiParameter)variable;
          final PsiType type = getClosureParameterType(parameter);
          if (type != null) {
            types.add(SupertypeConstraint.create(type));
          }
        }
      }
    }

    final String originalText = elementToBuildTemplate.getText();

    final TypeInfo typeInfo = getOrCreateTypeElement(parent, elementToBuildTemplate);
    final PsiElement replaceElement = typeInfo.elementToReplace;

    TypeConstraint[] constraints = types.toArray(new TypeConstraint[types.size()]);
    ChooseTypeExpression chooseTypeExpression = new ChooseTypeExpression(constraints, element.getManager(), replaceElement.getResolveScope());

    TemplateBuilderImpl builder = new TemplateBuilderImpl(elementToBuildTemplate);
    builder.replaceElement(replaceElement, chooseTypeExpression);

    final Document document = editor.getDocument();
    final RangeMarker rangeMarker = document.createRangeMarker(elementToBuildTemplate.getTextRange());
    rangeMarker.setGreedyToRight(true);
    rangeMarker.setGreedyToLeft(true);

    final PsiElement afterPostprocess = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(elementToBuildTemplate);
    final Template template = builder.buildTemplate();

    TextRange range = afterPostprocess.getTextRange();
    document.deleteString(range.getStartOffset(), range.getEndOffset());

    TemplateManager templateManager = TemplateManager.getInstance(project);
    templateManager.startTemplate(editor, template, new TemplateEditingAdapter() {
      @Override
      public void templateFinished(Template template, boolean brokenOff) {
        if (brokenOff) {
          ApplicationManager.getApplication().runWriteAction(new Runnable() {
            @Override
            public void run() {
              if (rangeMarker.isValid()) {
                document.replaceString(rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), originalText);
                editor.getCaretModel().moveToOffset(rangeMarker.getStartOffset() + typeInfo.originalOffset);
              }
            }
          });
        }
      }
    });

  }

  @Nullable
  private static PsiType getClosureParameterType(@NotNull PsiParameter parameter) {
    final PsiElement scope = parameter.getDeclarationScope();
    final PsiType type;
    if (scope instanceof GrClosableBlock) {
      type = ClosureParameterEnhancer.inferType((GrClosableBlock)scope, ((GrParameterList)parameter.getParent()).getParameterIndex(parameter));
    }
    else {
      type = null;
    }
    return type;
  }

  private static class TypeInfo {
    final PsiElement elementToReplace;
    final int originalOffset;

    TypeInfo(PsiElement element, int offset) {
      originalOffset = offset;
      elementToReplace = element;
    }
  }

  @NotNull
  private static TypeInfo getOrCreateTypeElement(@NotNull PsiElement parent,
                                                 @NotNull PsiElement elementToBuildTemplateOn) {
    GrModifierList modifierList = getModifierList(parent);

    if (modifierList != null && modifierList.hasModifierProperty(GrModifier.DEF) && modifierList.getModifiers().length == 1) {
      PsiElement modifier = PsiUtil.findModifierInList(modifierList, GrModifier.DEF);
      LOG.assertTrue(modifier != null);
      int modifierOffset = modifier.getTextRange().getEndOffset() - elementToBuildTemplateOn.getTextRange().getStartOffset();
      return new TypeInfo(modifier, modifierOffset);
    }
    else {
      int nameElementOffset;

      final PsiClassType typeToUse = TypesUtil.createType("Abc", parent);
      if (elementToBuildTemplateOn instanceof GrVariableDeclaration) {
        GrVariableDeclaration decl = (GrVariableDeclaration)elementToBuildTemplateOn;
        decl.setType(typeToUse);
        nameElementOffset = decl.getModifierList().getTextRange().getEndOffset() - elementToBuildTemplateOn.getTextRange().getStartOffset();
      }
      else {
        GrVariable var = (GrVariable)parent;
        var.setType(typeToUse);
        nameElementOffset = var.getNameIdentifierGroovy().getTextRange().getStartOffset() -
                            elementToBuildTemplateOn.getTextRange().getStartOffset();
      }

      return new TypeInfo(getTypeElement(parent), nameElementOffset);
    }
  }

  @Nullable
  private static GrTypeElement getTypeElement(PsiElement parent) {
    if (parent instanceof GrVariable) {
      return ((GrVariable)parent).getTypeElementGroovy();
    }
    else {
      return ((GrVariableDeclaration)parent).getTypeElementGroovy();
    }
  }

  @Nullable
  private static GrModifierList getModifierList(PsiElement parent) {
    GrModifierList modifierList;

    if (parent instanceof GrVariable) {
      modifierList = ((GrVariable)parent).getModifierList();
    }
    else {
      modifierList = ((GrVariableDeclaration)parent).getModifierList();
    }
    return modifierList;
  }

  @NotNull
  @Override
  protected PsiElementPredicate getElementPredicate() {
    return new PsiElementPredicate() {
      @Override
      public boolean satisfiedBy(PsiElement element) {
        PsiElement parent = element.getParent();

        PsiElement pparent;
        if (isNameIdentifierOfVariable(element, parent) || isModifierListOfVar(element, parent)) {
          pparent = parent.getParent();
        }
        else if (isModifierListOfVarDecl(element, parent)) {
          pparent = parent;
        }
        else {
          return false;
        }

        if (pparent instanceof GrVariableDeclaration) {
          if (((GrVariableDeclaration)pparent).getTypeElementGroovy() != null) return false;

          GrVariable[] variables = ((GrVariableDeclaration)pparent).getVariables();
          for (GrVariable variable : variables) {
            if (isVarDeclaredWithInitializer(variable)) return true;
          }
        }
        else if (pparent instanceof GrForInClause) {
          final GrVariable variable = ((GrForInClause)pparent).getDeclaredVariable();
          return variable != null && variable.getTypeElementGroovy() == null && PsiUtil.extractIteratedType((GrForInClause)pparent) != null;
        }
        else if (parent instanceof GrParameter && pparent instanceof GrParameterList) {
          return ((GrParameter)parent).getTypeElementGroovy() == null && getClosureParameterType((PsiParameter)parent) != null;
        }
        else {
          final GrVariable variable = (GrVariable)parent;
          return variable.getTypeElementGroovy() == null && isVarDeclaredWithInitializer(variable);
        }

        return false;
      }

      private boolean isModifierListOfVarDecl(PsiElement element, PsiElement parent) {
        return parent instanceof GrVariableDeclaration && ((GrVariableDeclaration)parent).getModifierList() == element;
      }

      private boolean isModifierListOfVar(PsiElement element, PsiElement parent) {
        return parent instanceof GrVariable && ((GrVariable)parent).getModifierList() == element;
      }


      private boolean isNameIdentifierOfVariable(PsiElement element, PsiElement parent) {
        return parent instanceof GrVariable &&
              ((GrVariable)parent).getTypeElementGroovy() == null &&
              element == ((GrVariable)parent).getNameIdentifierGroovy();
      }
    };
  }

  private static boolean isVarDeclaredWithInitializer(GrVariable variable) {
    GrExpression initializer = variable.getInitializerGroovy();
    return initializer != null && initializer.getType() != null;
  }
}
