// Copyright 2000-2020 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.model.search;

import com.intellij.lang.Language;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.search.SearchScope;
import com.intellij.util.Query;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;

public interface SearchWordQueryBuilder {

  /**
   * Orders to search word in files which contain {@code containerName} first.
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder withContainerName(@Nullable String containerName);

  /**
   * Sets case sensitivity.<br/>
   * The query is case sensitive by default, so this method might be used to make the query case insensitive.
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder caseSensitive(boolean caseSensitive);

  /**
   * Orders to search occurrences in given contexts.
   *
   * @see com.intellij.psi.search.UsageSearchContext
   */
  @Contract(value = "_, _ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder inContexts(@NotNull SearchContext context, SearchContext @NotNull ... otherContexts);

  /**
   * Orders to search occurrences in given contexts.
   *
   * @see com.intellij.psi.search.UsageSearchContext
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder inContexts(@NotNull Set<SearchContext> contexts);

  /**
   * Orders to search occurrences in given search scope.
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder inScope(@NotNull SearchScope searchScope);

  /**
   * Orders to search occurrences in files of given types.
   */
  @Contract(value = "_, _ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder restrictFileTypes(@NotNull FileType fileType, FileType @NotNull ... fileTypes);

  /**
   * Orders to search occurrences in files of given language.
   * <br/>
   * For example {@code inFilesWithLanguage(JavaLanguage.INSTANCE)} will produce occurrences
   * from Java files and JSP files (since JSP contains code with JavaLanguage)
   * <p>
   * This only checks the host file language.
   * </p>
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder inFilesWithLanguage(@NotNull Language language);

  /**
   * Orders to search occurrences in files of given language and its dialects.
   * <p>
   * Same as {@link #inFilesWithLanguage}, except the language is matched with dialects.
   * </p>
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder inFilesWithLanguageOfKind(@NotNull Language language);

  /**
   * Orders to include occurrences in language injections of any language as well as occurrences in host files.
   */
  @Contract(value = "-> new", pure = true)
  @NotNull
  SearchWordQueryBuilder includeInjections();

  /**
   * Orders to search occurrences in language injections (instead of host files).
   */
  @Contract(value = "-> new", pure = true)
  @NotNull
  SearchWordQueryBuilder inInjections();

  /**
   * Orders to search occurrences in language injections (instead of host files) of given language.
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder inInjections(@NotNull Language language);

  /**
   * Orders to search occurrences in language injections (instead of host files) of given language and its dialects.
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  SearchWordQueryBuilder inInjectionsOfKind(@NotNull Language language);

  /**
   * @param mapper pure function which is run once per each occurrence
   * @return query which returns results of applying the {@code mapper} to each occurrence
   */
  @Contract(value = "_ -> new", pure = true)
  @NotNull
  <T> Query<? extends T> buildQuery(@NotNull LeafOccurrenceMapper<T> mapper);

  /**
   * @return query which generates occurrences by traversing the tree up starting from the offset
   */
  @Contract(value = "-> new", pure = true)
  @NotNull
  Query<? extends TextOccurrence> buildOccurrenceQuery();
}

@@ -662,34 +662,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -948,34 +948,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -1192,34 +1192,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -1481,34 +1481,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -1680,34 +1680,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -1877,34 +1877,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -2359,34 +2359,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -2687,34 +2687,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -2944,34 +2944,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -3137,34 +3137,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -3345,34 +3345,32 @@
 true)%0A  @NotNull
-%0A 
  SearchWordQuery
@@ -3604,18 +3604,16 @@
 @NotNull
-%0A 
  SearchW
@@ -3889,32 +3889,36 @@
 , pure = true)%0A 
+ %3CT%3E
  @NotNull%0A  %3CT%3E 
@@ -3910,22 +3910,16 @@
 @NotNull
-%0A  %3CT%3E
  Query%3C?
@@ -4085,14 +4085,43 @@
 the 
-offset
+bottom-most element with occurrence
 %0A   
@@ -4176,18 +4176,16 @@
 @NotNull
-%0A 
  Query%3C?

reformat SearchWordQueryBuilder, clarify #buildOccurrenceQuery docs