// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.structuralsearch;

import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
import java.util.HashMap;

import java.util.Map;

/**
 * @author Eugene.Kudelevsky
 */
public class DocumentBasedReplaceHandler extends StructuralReplaceHandler {
  private final Project myProject;
  private final Map<ReplacementInfo, RangeMarker> myRangeMarkers = new HashMap<>();

  public DocumentBasedReplaceHandler(Project project) {
    myProject = project;
  }

  public void replace(ReplacementInfo info, ReplaceOptions options) {
    if (info.getMatchesCount() == 0) return;
    RangeMarker rangeMarker = myRangeMarkers.get(info);
    Document document = rangeMarker.getDocument();
    document.replaceString(rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), info.getReplacement());
    PsiDocumentManager.getInstance(myProject).commitDocument(document);
  }

  @Override
  public void prepare(ReplacementInfo info) {
  MatchResult result = info.getMatchResult();
    PsiElement element = result.getMatch();
    PsiFile file = element instanceof PsiFile ? (PsiFile)element : element.getContainingFile();
    Document document = PsiDocumentManager.getInstance(myProject).getDocument(file);
    assert document !=  null;
    RangeMarker rangeMarker = document.createRangeMarker(element.getTextRange());
    rangeMarker.setGreedyToLeft(true);
    rangeMarker.setGreedyToRight(true);
    myRangeMarkers.put(info, rangeMarker);
  }
}

@@ -18,9 +18,9 @@
 -201
-7
+8
  Jet
@@ -312,16 +312,60 @@
 roject;%0A
+import com.intellij.openapi.util.TextRange;%0A
 import c
@@ -440,41 +440,8 @@
 nt;%0A
-import com.intellij.psi.PsiFile;%0A
 impo
@@ -573,16 +573,17 @@
 ntInfo;%0A
+%0A
 import j
@@ -600,17 +600,16 @@
 ashMap;%0A
-%0A
 import j
@@ -1020,52 +1020,13 @@
     
-if (info.getMatchesCount() == 0) return;%0A   
+final
  Ran
@@ -1074,24 +1074,30 @@
 (info);%0A    
+final 
 Document doc
@@ -1381,164 +1381,188 @@
 %7B%0A  
-MatchResult result = info.getMatchResult();%0A    PsiElement element = result.getMatch();%0A    PsiFile file = element instanceof PsiFile ? (PsiFile)element : e
+  final PsiElement firstElement = info.getMatch(0);%0A    if (firstElement == null) return;%0A    final Document document = PsiDocumentManager.getInstance(myProject).getDocument(firstE
 leme
@@ -1587,21 +1587,20 @@
 le()
+)
 ;%0A    
-Documen
+asser
 t do
@@ -1610,104 +1610,541 @@
 ent 
+!
 = 
-PsiDocumentManager.getInstance(myProject).getDocument(file);%0A    assert documen
+ null;%0A    final TextRange range = firstElement.getTextRange();%0A    int startOffset = range.getStartOffset();%0A    int endOffset = range.getEndOffset();%0A    int count = info.getMatchesCount();%0A    for (int i = 1; i %3C count; i++) %7B%0A      final PsiElement match = info.getMatch(i);%0A      if (match == null) %7B%0A        continue;%0A      %7D%0A      final TextRange range1 = match.getTextRange();%0A      startOffset = Math.min(startOffset, range1.getStartOffset());%0A      endOffse
 t 
-!
 = 
- null;%0A   
+Math.max(endOffset, range1.getEndOffset());%0A    %7D%0A    final
  Ran
@@ -2197,30 +2197,30 @@
 ker(
-element.getTextRange()
+startOffset, endOffset
 );%0A 

fix document based replace for multiline results (IDEA-187663)