// Copyright 2000-2019 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.plugin.ui;

import com.intellij.codeInsight.completion.CompletionContributor;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.structuralsearch.MatchOptions;
import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
import org.jetbrains.annotations.NotNull;

public class StructuralSearchTemplatesCompletionContributor extends CompletionContributor {
  @Override
  public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
    final StructuralSearchDialog dialog = parameters.getEditor().getUserData(StructuralSearchDialog.STRUCTURAL_SEARCH_DIALOG);
    if (dialog == null) return;
    result.runRemainingContributors(parameters, cr -> {
      if (cr.getLookupElement().getObject() instanceof String) return;
      result.passResult(cr);
    });

    String prefix = parameters.isExtendedCompletion()
                    ? TextFieldWithAutoCompletionListProvider.getCompletionPrefix(parameters)
                    : parameters.getOriginalFile().getText().substring(0, parameters.getOffset());
    CompletionResultSet insensitive = result.withPrefixMatcher(new CamelHumpMatcher(prefix));
    ConfigurationManager configurationManager = ConfigurationManager.getInstance(parameters.getPosition().getProject());
    for (String configurationName: configurationManager.getAllConfigurationNames()) {
      Configuration configuration = configurationManager.findConfigurationByName(configurationName);
      if (configuration == null) continue;
      final MatchOptions matchOptions = configuration.getMatchOptions();
      LookupElementBuilder element = LookupElementBuilder.create(configuration, matchOptions.getSearchPattern())
        .withLookupString(configurationName)
        .withTailText(" (" + StringUtil.toLowerCase(matchOptions.getFileType().getName()) +
                      (configuration instanceof SearchConfiguration ? " search" : " replace") + " template)", true)
        .withCaseSensitivity(false)
        .withPresentableText(configurationName)
        .withInsertHandler((InsertionContext context, LookupElement item) -> context.setLaterRunnable(
          () -> dialog.loadConfiguration((Configuration)item.getObject())
        ));
      insensitive.addElement(element);
    }
  }
}

@@ -617,24 +617,133 @@
 entBuilder;%0A
+import com.intellij.codeInsight.template.impl.TemplateImplUtil;%0Aimport com.intellij.openapi.editor.Document;%0A
 import com.i
@@ -938,16 +938,49 @@
 tNull;%0A%0A
+import java.util.LinkedHashSet;%0A%0A
 public c
@@ -1356,61 +1356,618 @@
 rn;%0A
+%0A
     
-result.runRemainingContributors(parameters, cr -%3E
+final Document document = parameters.getEditor().getDocument();%0A    final int end = parameters.getOffset();%0A    final int line = document.getLineNumber(end);%0A    final int start = document.getLineStartOffset(line);%0A    String shortPrefix = TextFieldWithAutoCompletionListProvider.getCompletionPrefix(parameters);%0A    final CharSequence text = document.getCharsSequence();%0A    if (StringUtil.startsWithChar(shortPrefix, '$')) %7B%0A      shortPrefix = shortPrefix.substring(1);%0A      final LinkedHashSet%3CString%3E variableNames = TemplateImplUtil.parseVariableNames(text);%0A      for (String name : variableNames)
  %7B%0A 
@@ -1975,355 +1975,907 @@
     
+ 
+ 
 if (
-cr.getLookupElement().getObject() instanceof String) return;%0A      result.passResult(cr);%0A    %7D);%0A%0A    String prefix = parameters.isExtendedCompletion()%0A                    ? TextFieldWithAutoCompletionListProvider.getCompletionPrefix(parameters)%0A             
+name.startsWith(shortPrefix) && !name.equals(shortPrefix)) %7B%0A          result.addElement(LookupElementBuilder.create('$' + name + '$')%0A          .withInsertHandler((context, item) -%3E %7B%0A            final int offset = context.getTailOffset();%0A            if (text.length() %3E offset + 1) %7B%0A              final char c = text.charAt(offset);%0A              if (c == '$') %7B%0A                document.deleteString(offset, offset + 1);%0A              %7D%0A            %7D%0A          %7D));%0A        %7D%0A      %7D%0A    %7D%0A    final String prefix = parameters.isExtendedCompletion()%0A                          ? shortPrefix%0A                          : text.subSequence(start, end).toString();%0A    if (StringUtil.containsChar(prefix, '$')) %7B%0A      return;%0A
     
+%7D%0A
    
-: parameters.getOriginalFile().getText().substring(0, parameters.getOffset()
+ result.runRemainingContributors(parameters, cr -%3E %7B%0A      if (cr.getLookupElement().getObject() instanceof String) return;%0A      result.passResult(cr);%0A    %7D
 );%0A 

improve completion (IDEA-210319)