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

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;

public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.editorActions.DeclarationJoinLinesHandler");

  @Override
  public int tryJoinLines(final Document document, final PsiFile file, final int start, final int end) {
    PsiElement elementAtStartLineEnd = file.findElementAt(start);
    PsiElement elementAtNextLineStart = file.findElementAt(end);
    if (elementAtStartLineEnd == null || elementAtNextLineStart == null) return -1;

    // first line.
    if (!(elementAtStartLineEnd instanceof PsiJavaToken)) return -1;
    PsiJavaToken lastFirstLineToken = (PsiJavaToken)elementAtStartLineEnd;
    if (lastFirstLineToken.getTokenType() != JavaTokenType.SEMICOLON) return -1;
    if (!(lastFirstLineToken.getParent() instanceof PsiLocalVariable)) return -1;
    PsiLocalVariable var = (PsiLocalVariable)lastFirstLineToken.getParent();

    if (!(var.getParent() instanceof PsiDeclarationStatement)) return -1;
    PsiDeclarationStatement decl = (PsiDeclarationStatement)var.getParent();
    if (decl.getDeclaredElements().length > 1) return -1;

    //second line.
    if (!(elementAtNextLineStart instanceof PsiJavaToken)) return -1;
    PsiJavaToken firstNextLineToken = (PsiJavaToken)elementAtNextLineStart;
    if (firstNextLineToken.getTokenType() != JavaTokenType.IDENTIFIER) return -1;
    if (!(firstNextLineToken.getParent() instanceof PsiReferenceExpression)) return -1;
    PsiReferenceExpression ref = (PsiReferenceExpression)firstNextLineToken.getParent();
    PsiElement refResolved = ref.resolve();

    PsiManager psiManager = ref.getManager();
    if (!psiManager.areElementsEquivalent(refResolved, var)) return -1;
    if (!(ref.getParent() instanceof PsiAssignmentExpression)) return -1;
    PsiAssignmentExpression assignment = (PsiAssignmentExpression)ref.getParent();
    if (!(assignment.getParent() instanceof PsiExpressionStatement)) return -1;

    if (ReferencesSearch.search(var, new LocalSearchScope(assignment.getRExpression()), false).findFirst() != null) {
      return -1;
    }

    final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
    final PsiExpression initializerExpression = getInitializerExpression(var, assignment);
    if (initializerExpression == null) return -1;

    PsiExpressionStatement statement = (PsiExpressionStatement)assignment.getParent();

    int startOffset = decl.getTextRange().getStartOffset();
    try {
      PsiDeclarationStatement newDecl = factory.createVariableDeclarationStatement(var.getName(), var.getType(), initializerExpression);
      PsiVariable newVar = (PsiVariable)newDecl.getDeclaredElements()[0];
      if (var.getModifierList().getText().length() > 0) {
        PsiUtil.setModifierProperty(newVar, PsiModifier.FINAL, true);
      }
      newVar.getModifierList().replace(var.getModifierList());
      PsiVariable variable = (PsiVariable)newDecl.getDeclaredElements()[0];
      final int offsetBeforeEQ = variable.getNameIdentifier().getTextRange().getEndOffset();
      final int offsetAfterEQ = variable.getInitializer().getTextRange().getStartOffset() + 1;
      newDecl = (PsiDeclarationStatement)CodeStyleManager.getInstance(psiManager).reformatRange(newDecl, offsetBeforeEQ, offsetAfterEQ);

      PsiElement child = statement.getLastChild();
      while (child instanceof PsiComment || child instanceof PsiWhiteSpace) {
        child = child.getPrevSibling();
      }
      if (child != null && child.getNextSibling() != null) {
        newDecl.addRangeBefore(child.getNextSibling(), statement.getLastChild(), null);
      }

      decl.replace(newDecl);
      statement.delete();
      return startOffset + newDecl.getTextRange().getEndOffset() - newDecl.getTextRange().getStartOffset();
    }
    catch (IncorrectOperationException e) {
      LOG.error(e);
      return -1;
    }
  }

  public static PsiExpression getInitializerExpression(PsiLocalVariable var,
                                                       PsiAssignmentExpression assignment) {
    PsiExpression initializerExpression;
    final IElementType originalOpSign = assignment.getOperationTokenType();
    if (originalOpSign == JavaTokenType.EQ) {
      initializerExpression = assignment.getRExpression();
    }
    else {
      if (var.getInitializer() == null) return null;
      String opSign = null;
      if (originalOpSign == JavaTokenType.ANDEQ) {
        opSign = "&";
      }
      else if (originalOpSign == JavaTokenType.ASTERISKEQ) {
        opSign = "*";
      }
      else if (originalOpSign == JavaTokenType.DIVEQ) {
        opSign = "/";
      }
      else if (originalOpSign == JavaTokenType.GTGTEQ) {
        opSign = ">>";
      }
      else if (originalOpSign == JavaTokenType.GTGTGTEQ) {
        opSign = ">>>";
      }
      else if (originalOpSign == JavaTokenType.LTLTEQ) {
        opSign = "<<";
      }
      else if (originalOpSign == JavaTokenType.MINUSEQ) {
        opSign = "-";
      }
      else if (originalOpSign == JavaTokenType.OREQ) {
        opSign = "|";
      }
      else if (originalOpSign == JavaTokenType.PERCEQ) {
        opSign = "%";
      }
      else if (originalOpSign == JavaTokenType.PLUSEQ) {
        opSign = "+";
      }
      else if (originalOpSign == JavaTokenType.XOREQ) {
        opSign = "^";
      }

      try {
        final Project project = var.getProject();
        final String initializerText = var.getInitializer().getText() + opSign + assignment.getRExpression().getText();
        initializerExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText(initializerText, var);
        initializerExpression = (PsiExpression)CodeStyleManager.getInstance(project).reformat(initializerExpression);
      }
      catch (IncorrectOperationException e) {
        LOG.error(e);
        return null;
      }
    }
    return initializerExpression;
  }
}
