package com.reason.ide.insight.provider;

import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionProvider;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.StubIndex;
import com.intellij.util.ProcessingContext;
import com.intellij.util.PsiIconUtil;
import com.reason.ide.search.IndexKeys;
import com.reason.lang.MlTypes;
import com.reason.lang.core.psi.PsiModule;
import com.reason.lang.core.psi.PsiNamedElement;
import com.reason.lang.core.psi.PsiUpperSymbol;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;

public class ExpressionCompletionProvider extends CompletionProvider<CompletionParameters> {
    public ExpressionCompletionProvider(MlTypes types) {

    }

    @Override
    protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet resultSet) {
        System.out.println("»» Expression completion");

        Project project = parameters.getOriginalFile().getProject();
        PsiElement cursorElement = parameters.getOriginalPosition();
        PsiElement previousElement = cursorElement == null ? null : cursorElement.getPrevSibling();
        previousElement = previousElement == null ? null : previousElement.getPrevSibling();

        // Find the expression path

        if (previousElement instanceof PsiUpperSymbol) {
            // Expression of module
            String upperName = ((PsiUpperSymbol) previousElement).getName();
            if (upperName != null) {
                PsiModule module = null;

                Collection<PsiModule> modules = StubIndex.getElements(IndexKeys.MODULES, upperName, project, GlobalSearchScope.allScope(project), PsiModule.class);
                if (!modules.isEmpty()) {
                    // TODO: Find the correct module path
                    module = modules.iterator().next();
                }

                if (module != null) {
                    Collection<PsiNamedElement> expressions = module.getExpressions();
                    for (PsiNamedElement expression : expressions) {
                        resultSet.addElement(
                                LookupElementBuilder.
                                        create(expression).
                                        withIcon(PsiIconUtil.getProvidersIcon(expression, 0))
                        );
                    }
                }
            }
        }
    }
}

@@ -393,199 +393,180 @@
 lij.
-psi.search.GlobalSearchScope;%0Aimport com.intellij.psi.stubs.StubIndex;%0Aimport com.intellij.util.ProcessingContext;%0Aimport com.intellij.util.PsiIconUtil;%0Aimport com.reason.ide.search.IndexKeys
+util.ProcessingContext;%0Aimport com.intellij.util.PsiIconUtil;%0Aimport com.reason.lang.MlTypes;%0Aimport com.reason.lang.core.MlFileType;%0Aimport com.reason.lang.core.RmlPsiUtil
 ;%0Aim
@@ -578,39 +578,52 @@
 com.reason.lang.
-MlTypes
+core.psi.PsiExternal
 ;%0Aimport com.rea
@@ -1146,16 +1146,18 @@
         
+//
 System.o
@@ -1315,24 +1315,16 @@
 ters.get
-Original
 Position
@@ -1367,39 +1367,8 @@
 nt =
- cursorElement == null ? null :
  cur
@@ -1754,373 +1754,336 @@
     
-PsiModule module = null;%0A%0A                Collection%3CPsiModule%3E modules = StubIndex.getElements(IndexKeys.MODULES, upperName, project, GlobalSearchScope.allScope(project), PsiModule.class);%0A                if (!modules.isEmpty()) %7B%0A                    // TODO: Find the correct module path%0A                    module = modules.iterator().next();%0A                %7D%0A%0A
+Collection%3CPsiModule%3E modules = RmlPsiUtil.findModules(project, upperName, MlFileType.interfaceOrImplementation);%0A                // TODO: Find the correct module path, and filter the result%0A                Collection%3CPsiModule%3E resolvedModules = modules;%0A%0A                for (PsiModule resolvedModule : resolvedModules) %7B%0A    
     
@@ -2098,17 +2098,25 @@
     if (
-m
+resolvedM
 odule !=
@@ -2116,32 +2116,36 @@
 dule != null) %7B%0A
+    
                 
@@ -2186,25 +2186,33 @@
 pressions = 
-m
+resolvedM
 odule.getExp
@@ -2219,24 +2219,28 @@
 ressions();%0A
+    
             
@@ -2320,16 +2320,20 @@
         
+  
+  
 resultSe
@@ -2346,16 +2346,20 @@
 lement(%0A
+    
         
@@ -2404,16 +2404,20 @@
 uilder.%0A
+    
         
@@ -2468,16 +2468,244 @@
 ssion).%0A
+                                            // TODO Use a type provider%0A                                                    withTypeText(expression instanceof PsiExternal ? ((PsiExternal) expression).getSignature() : null).%0A    
         
@@ -2814,18 +2814,48 @@
         
-);
+    );%0A                        %7D
 %0A       

Work on expression completion