/*
 * 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.intention.impl.CreateFieldFromParameterActionBase;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
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.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Max Medvedev
 */
public class GrCreateFieldForParameterIntention extends CreateFieldFromParameterActionBase {

  @Override
  protected boolean isAvailable(PsiParameter parameter) {
    PsiElement scope = parameter.getDeclarationScope();
    if (!(scope instanceof GrMethod)) return false;
    if (((GrMethod)scope).getContainingClass() == null) return false;

    if (checkAssignmentToFieldExists(parameter)) return false;

    return true;
  }

  @Override
  protected PsiType getSubstitutedType(PsiParameter parameter) {
    return GroovyRefactoringUtil.getSubstitutedType((GrParameter)parameter);
  }

  private static boolean checkAssignmentToFieldExists(PsiParameter parameter) {
    for (PsiReference reference : ReferencesSearch.search(parameter).findAll()) {
      PsiElement element = reference.getElement();
      if (element instanceof GrReferenceExpression &&
          element.getParent() instanceof GrAssignmentExpression &&
          ((GrAssignmentExpression)element.getParent()).getRValue() == element) {
        GrAssignmentExpression parent = ((GrAssignmentExpression)element.getParent());
        GrExpression value = parent.getLValue();
        if (value instanceof GrReferenceExpression && ((GrReferenceExpression)value).resolve() instanceof PsiField) return true;
      }
    }
    return false;
  }

  @Override
  protected void performRefactoring(Project project,
                                    PsiClass targetClass,
                                    PsiMethod method,
                                    PsiParameter myParameter,
                                    PsiType type,
                                    String fieldName,
                                    boolean methodStatic,
                                    boolean isFinal) {
    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);

    if (targetClass.findFieldByName(fieldName, false) == null) {
      String[] modifiers = getModifiers(methodStatic, isFinal);
      GrVariableDeclaration fieldDeclaration = factory.createFieldDeclaration(modifiers, fieldName, null, type);
      GrVariableDeclaration inserted = (GrVariableDeclaration)targetClass.add(fieldDeclaration);
      JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted);
    }

    GrOpenBlock block = ((GrMethod)method).getBlock();
    if (block == null) return;

    GrAssignmentExpression assignment = createAssignment(targetClass, myParameter, fieldName, methodStatic, factory);
    GrStatement anchor = getAnchor(block);

    GrStatement statement = block.addStatementBefore(assignment, anchor);
    JavaCodeStyleManager.getInstance(project).shortenClassReferences(statement);
  }

  private static GrAssignmentExpression createAssignment(PsiClass targetClass,
                                                         PsiParameter myParameter,
                                                         String fieldName,
                                                         boolean methodStatic,
                                                         GroovyPsiElementFactory factory) {
    StringBuilder builder = new StringBuilder();
    if (methodStatic) {
      builder.append(targetClass.getQualifiedName());
      builder.append('.');
    }
    else {
      builder.append("this.");
    }
    builder.append(fieldName);
    builder.append("=").append(myParameter.getName());
    return (GrAssignmentExpression)factory.createStatementFromText(builder.toString());
  }

  @Nullable
  private static GrStatement getAnchor(GrOpenBlock block) {
    GrStatement[] statements = block.getStatements();
    GrStatement fist = ArrayUtil.getFirstElement(statements);
    if (fist instanceof GrConstructorInvocation) {
      return statements.length > 1 ? statements[1] : null;
    }
    else {
      return fist;
    }
  }

  private static String[] getModifiers(boolean aStatic, boolean aFinal) {
    List<String> list = new ArrayList<String>();
    list.add(PsiModifier.PRIVATE);
    if (aStatic) list.add(PsiModifier.STATIC);
    if (aFinal) list.add(PsiModifier.FINAL);
    return ArrayUtil.toStringArray(list);
  }
}
