package com.intellij.structuralsearch.impl.matcher.compiler;

import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.cache.CacheManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.structuralsearch.MatchOptions;
import com.intellij.util.Processor;
import gnu.trove.THashMap;

import java.util.Set;

/**
 * @author Maxim.Mossienko
*/
class FindInFilesOptimizingSearchHelper extends OptimizingSearchHelperBase {
  private final MyFileProcessor myFileProcessor;
  private THashMap<PsiFile,PsiFile> filesToScan;
  private THashMap<PsiFile,PsiFile> filesToScan2;

  private final boolean myFindMatchingFiles;
  private final Project myProject;

  FindInFilesOptimizingSearchHelper(CompileContext context, boolean findMatchingFiles, Project project) {
    super(context);
    myFindMatchingFiles = findMatchingFiles;
    myProject = project;

    if (myFindMatchingFiles && filesToScan == null) {
      filesToScan = new THashMap<PsiFile, PsiFile>();
      filesToScan2 = new THashMap<PsiFile, PsiFile>();
    }
    myFileProcessor = new MyFileProcessor();
  }

  public boolean doOptimizing() {
    return myFindMatchingFiles;
  }

  public void clear() {
    super.clear();

    if (filesToScan != null) {
      filesToScan.clear();
      filesToScan2.clear();
    }
  }

  protected void doAddSearchWordInCode(final String refname) {
    final MatchOptions options = context.getOptions();
    CacheManager.SERVICE.getInstance(myProject).processFilesWithWord(myFileProcessor, refname, UsageSearchContext.IN_CODE,
                                                                     (GlobalSearchScope)options.getScope(), options.isCaseSensitiveMatch());
  }

  protected void doAddSearchWordInText(final String refname) {
    final MatchOptions options = context.getOptions();
    CacheManager.SERVICE.getInstance(myProject).processFilesWithWord(myFileProcessor, refname, UsageSearchContext.IN_PLAIN_TEXT,
                                                                     (GlobalSearchScope)options.getScope(), options.isCaseSensitiveMatch());
  }

  protected void doAddSearchWordInComments(final String refname) {
    final MatchOptions options = context.getOptions();
    CacheManager.SERVICE.getInstance(myProject).processFilesWithWord(myFileProcessor, refname, UsageSearchContext.IN_COMMENTS,
                                                                     (GlobalSearchScope)options.getScope(), options.isCaseSensitiveMatch());
  }

  protected void doAddSearchWordInLiterals(final String refname) {
    final MatchOptions options = context.getOptions();
    CacheManager.SERVICE.getInstance(myProject).processFilesWithWord(myFileProcessor, refname, UsageSearchContext.IN_STRINGS,
                                                                     (GlobalSearchScope)options.getScope(), options.isCaseSensitiveMatch());
  }

  public void endTransaction() {
    super.endTransaction();
    THashMap<PsiFile,PsiFile> map = filesToScan;
    if (map.size() > 0) map.clear();
    filesToScan = filesToScan2;
    filesToScan2 = map;
  }

  public Set<PsiFile> getFilesSetToScan() {
    return filesToScan.keySet();
  }

  private class MyFileProcessor implements Processor<PsiFile> {
    public boolean process(PsiFile file) {
      if (scanRequest == 0 || filesToScan.get(file) != null) {
        filesToScan2.put(file,file);
      }
      return true;
    }
  }

}

@@ -392,19 +392,19 @@
 ve.THash
-Map
+Set
 ;%0A%0Aimpor
@@ -592,36 +592,28 @@
 rivate THash
-Map%3CPsiFile,
+Set%3C
 PsiFile%3E fil
@@ -633,36 +633,28 @@
 rivate THash
-Map%3CPsiFile,
+Set%3C
 PsiFile%3E fil
@@ -1022,37 +1022,28 @@
  = new THash
-Map%3CPsiFile, 
+Set%3C
 PsiFile%3E();%0A
@@ -1076,21 +1076,12 @@
 Hash
-Map%3CPsiFile, 
+Set%3C
 PsiF
@@ -2994,25 +2994,23 @@
     
-THashMap%3CPsiFile,
+final THashSet%3C
 PsiF
@@ -3201,17 +3201,8 @@
 Scan
-.keySet()
 ;%0A  
@@ -3357,25 +3357,22 @@
 can.
-get(file) != null
+contains(file)
 ) %7B%0A
@@ -3396,17 +3396,12 @@
 an2.
-put(file,
+add(
 file
@@ -3436,15 +3436,14 @@
 ;%0A    %7D%0A
+
   %7D%0A
-%0A
 %7D%0A

use a little less memory