package mobi.hsz.idea.gitignore.reference;

import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceHelper;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.util.containers.ContainerUtil;
import mobi.hsz.idea.gitignore.psi.GitignoreEntry;
import mobi.hsz.idea.gitignore.util.Utils;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;

public class GitReferenceSet extends FileReferenceSet {
    public GitReferenceSet(@NotNull GitignoreEntry element) {
        super(element);
    }

    @Override
    public FileReference createFileReference(TextRange range, int index, String text) {
        return new GitReference(this, range, index, text);
    }

    @Override
    public boolean isEndingSlashNotAllowed() {
        return false;
    }

    @NotNull
    @Override
    public Collection<PsiFileSystemItem> computeDefaultContexts() {
        PsiFile containingFile = getElement().getContainingFile();
        PsiDirectory containingDirectory = containingFile.getParent();
        return containingDirectory != null ? Collections.<PsiFileSystemItem>singletonList(containingDirectory) : super.computeDefaultContexts();
    }

    private class GitReference extends FileReference {
        public GitReference(@NotNull FileReferenceSet fileReferenceSet, TextRange range, int index, String text) {
            super(fileReferenceSet, range, index, text);
        }

        @NotNull
        @Override
        protected ResolveResult[] innerResolve(boolean caseSensitive) {
            LinkedList<ResolveResult> result = ContainerUtil.newLinkedList();
            PsiManager psiManager = PsiManager.getInstance(getElement().getProject());
            for (PsiFileSystemItem context : getContexts()) {
                VirtualFile contextVirtualFile = context.getVirtualFile();
                if (contextVirtualFile != null) {
                    String regexFromGlob = Utils.createRegexFromGlob(getCanonicalText());
                    for (VirtualFile file : contextVirtualFile.getChildren()) {
                        if (file.getName().matches(regexFromGlob)) {
                            PsiFileSystemItem psiFileSystemItem = FileReferenceHelper.getPsiFileSystemItem(psiManager, file);
                            if (psiFileSystemItem != null) {
                                result.add(new PsiElementResolveResult(psiFileSystemItem));
                            }
                        }
                    }
                }
            }
            return result.isEmpty()
                    ? super.innerResolve(caseSensitive)
                    : result.toArray(new ResolveResult[result.size()]);
        }
    }
}

@@ -418,59 +418,8 @@
 et;%0A
-import com.intellij.util.containers.ContainerUtil;%0A
 impo
@@ -613,37 +613,8 @@
 ons;
-%0Aimport java.util.LinkedList;
 %0A%0Apu
@@ -1645,25 +1645,8 @@
  %7D%0A%0A
-        @NotNull%0A
     
@@ -1681,137 +1681,228 @@
 ted 
-ResolveResult%5B%5D innerResolve(boolean caseSensitive) %7B%0A            LinkedList%3CResolveResult%3E result = ContainerUtil.newLinkedList(
+void innerResolveInContext(@NotNull String text, @NotNull PsiFileSystemItem context, Collection%3CResolveResult%3E result, boolean caseSensitive) %7B%0A            super.innerResolveInContext(text, context, result, caseSensitive
 );%0A 
@@ -1991,74 +1991,8 @@
 ));%0A
-            for (PsiFileSystemItem context : getContexts()) %7B%0A    
     
@@ -2054,28 +2054,24 @@
 tualFile();%0A
-    
             
@@ -2120,20 +2120,16 @@
         
-    
 String r
@@ -2186,28 +2186,24 @@
 calText());%0A
-    
             
@@ -2282,28 +2282,24 @@
             
-    
 if (file.get
@@ -2351,28 +2351,24 @@
             
-   
- 
 PsiFileSyste
@@ -2473,28 +2473,24 @@
             
-    
 if (psiFileS
@@ -2538,20 +2538,16 @@
         
-   
- 
 result.a
@@ -2618,32 +2618,26 @@
             
-    %7D%0A  
+%7D%0A
             
@@ -2640,32 +2640,26 @@
             
-  %7D%0A    
+%7D%0A
             
@@ -2680,191 +2680,9 @@
     
-    %7D%0A            %7D%0A            return result.isEmpty()%0A                    ? super.innerResolve(caseSensitive)%0A                    : result.toArray(new ResolveResult%5Bresult.size()%5D);
+%7D
 %0A   

Fix possible compatibility issues with 138.* builds