package de.plushnikov.intellij.plugin.extension;

import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.SearchRequestCollector;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.Processor;
import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;

/**
 * Annas example: org.jetbrains.plugins.javaFX.fxml.refs.JavaFxControllerFieldSearcher
 */
public class LombokReferenceSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {

  public LombokReferenceSearcher() {
    super(true);
  }

  /**
   * Used by IDEA from 2018.2
   */
//  @Override
  public void processQuery(@NotNull ReferencesSearch.SearchParameters queryParameters, @NotNull Processor<? super PsiReference> consumer) {
    processQueryIntern(queryParameters);
  }

  /**
   * Used by IDEA before 2018.2
   */
//  @Override
  public void processQueryIntern(@NotNull ReferencesSearch.SearchParameters queryParameters, @NotNull Processor<PsiReference> consumer) {
    processQueryIntern(queryParameters);
  }

  private void processQueryIntern(@NotNull ReferencesSearch.SearchParameters queryParameters) {
    PsiElement refElement = queryParameters.getElementToSearch();

    if (refElement instanceof PsiField) {
      processPsiField((PsiField) refElement, queryParameters.getOptimizer());
    }
  }

  private void processPsiField(final PsiField refPsiField, final SearchRequestCollector collector) {
    final PsiClass containingClass = refPsiField.getContainingClass();
    if (null != containingClass) {
      processClassMethods(refPsiField, collector, containingClass);

      Arrays.stream(containingClass.getInnerClasses())
        .forEach(psiClass -> processClassMethods(refPsiField, collector, psiClass));
    }
  }

  private void processClassMethods(PsiField refPsiField, SearchRequestCollector collector, PsiClass containingClass) {
    Arrays.stream(containingClass.getMethods())
      .filter(LombokLightMethodBuilder.class::isInstance)
      .filter(psiMethod -> psiMethod.getNavigationElement() == refPsiField)
      .forEach(psiMethod -> {
        collector.searchWord(psiMethod.getName(), psiMethod.getUseScope(), UsageSearchContext.IN_CODE, true, psiMethod);
      });
  }

}

@@ -853,52 +853,8 @@
  %7D%0A%0A
-  /**%0A   * Used by IDEA from 2018.2%0A   */%0A//
   @O
@@ -970,423 +970,17 @@
 ssor
-%3C? super PsiReference%3E consumer) %7B%0A    processQueryIntern(queryParameters);%0A  %7D%0A%0A  /**%0A   * Used by IDEA before 2018.2%0A   */%0A//  @Override%0A  public void processQueryIntern(@NotNull ReferencesSearch.SearchParameters queryParameters, @NotNull Processor%3CPsiReference%3E consumer) %7B%0A    processQueryIntern(queryParameters);%0A  %7D%0A%0A  private void processQueryIntern(@NotNull ReferencesSearch.SearchParameters queryParameters
+ consumer
 ) %7B%0A

make method compatible to different idea versions