package com.redhat.ceylon.eclipse.code.correct;

import static com.redhat.ceylon.compiler.loader.AbstractModelLoader.JDK_MODULE_VERSION;
import static com.redhat.ceylon.compiler.typechecker.tree.Util.formatPath;
import static com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider.IMPORT;
import static com.redhat.ceylon.eclipse.util.ModuleQueries.getModuleQueryType;

import java.util.Collection;
import java.util.List;
import java.util.TreeSet;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension6;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;

import com.redhat.ceylon.cmr.api.JDKUtils;
import com.redhat.ceylon.cmr.api.ModuleQuery;
import com.redhat.ceylon.cmr.api.ModuleSearchResult;
import com.redhat.ceylon.cmr.api.ModuleSearchResult.ModuleDetails;
import com.redhat.ceylon.common.Versions;
import com.redhat.ceylon.compiler.typechecker.TypeChecker;
import com.redhat.ceylon.compiler.typechecker.model.Unit;
import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.eclipse.code.imports.ModuleImportUtil;

public class AddModuleImportProposal implements ICompletionProposal, 
        ICompletionProposalExtension6 {
    
    private final IProject project;
    private final Unit unit; 
    private final String name; 
    private final String version;
    
    AddModuleImportProposal(IProject project, Unit unit, ModuleDetails details) {
        this.project = project;
        this.unit = unit;
        this.name = details.getName();
        this.version = details.getLastVersion().getVersion();
    }
    
    AddModuleImportProposal(IProject project, Unit unit, String name, String version) {
        this.project = project;
        this.unit = unit;
        this.name = name;
        this.version = version;
    }
    
    @Override
    public void apply(IDocument document) {
        ModuleImportUtil.addModuleImport(project, 
                unit.getPackage().getModule(), 
                name, version);
    }

    @Override
    public Point getSelection(IDocument document) {
        return null;
    }

    @Override
    public String getAdditionalProposalInfo() {
        return null;
    }

    @Override
    public String getDisplayString() {
        return "Add 'import " + name + "' to module descriptor";
    }

    @Override
    public Image getImage() {
        return IMPORT;
    }

    @Override
    public IContextInformation getContextInformation() {
        return null;
    }

    @Override
    public StyledString getStyledDisplayString() {
        return CorrectionUtil.styleProposal(getDisplayString());
    }

    static void addModuleImportProposals(Collection<ICompletionProposal> proposals, 
            IProject project, TypeChecker tc, Node node) {
        Unit unit = node.getUnit();
        if (unit.getPackage().getModule().isDefault()) {
            return;
        }
        if (node instanceof Tree.Import) {
            node = ((Tree.Import) node).getImportPath();
        }
        List<Tree.Identifier> ids = ((Tree.ImportPath) node).getIdentifiers();
        String pkg = formatPath(ids);
        if (JDKUtils.isJDKAnyPackage(pkg)) {
            for (String mod: new TreeSet<String>(JDKUtils.getJDKModuleNames())) {
                if (JDKUtils.isJDKPackage(mod, pkg)) {
                    proposals.add(new AddModuleImportProposal(project, unit, mod, 
                            JDK_MODULE_VERSION));
                    return;
                }
            }
        }
        for (int i=ids.size(); i>0; i--) {
            String pn = formatPath(ids.subList(0, i));
            ModuleQuery query = new ModuleQuery(pn, getModuleQueryType(project));
            query.setBinaryMajor(Versions.JVM_BINARY_MAJOR_VERSION);
            query.setCount(2l);
            ModuleSearchResult msr = tc.getContext().getRepositoryManager()
                    .searchModules(query);
            ModuleDetails md = msr.getResult(pn);
            if (md!=null) {
                proposals.add(new AddModuleImportProposal(project, unit, md));
            }
            if (!msr.getResults().isEmpty()) break;
        }
    }

}

@@ -1408,23 +1408,16 @@
 tUtil;%0A%0A
-public 
 class Ad
@@ -3818,110 +3818,8 @@
   %7D%0A
-        for (int i=ids.size(); i%3E0; i--) %7B%0A            String pn = formatPath(ids.subList(0, i));%0A    
     
@@ -3858,18 +3858,31 @@
 leQuery(
-pn
+formatPath(ids)
 , getMod
@@ -3901,28 +3901,24 @@
 (project));%0A
-    
         quer
@@ -3974,28 +3974,24 @@
 N);%0A        
-  
-  
 query.setCou
@@ -3998,20 +3998,16 @@
 nt(2l);%0A
-    
         
@@ -4086,20 +4086,16 @@
         
- 
-   
 .searchM
@@ -4109,16 +4109,114 @@
 query);%0A
+        for (int i=ids.size(); i%3E0; i--) %7B%0A            String pn = formatPath(ids.subList(0, i));%0A
         
@@ -4368,33 +4368,42 @@
 ));%0A            
-%7D
+    break;
 %0A            if 
@@ -4403,47 +4403,9 @@
     
-if (!msr.getResults().isEmpty()) break;
+%7D
 %0A   

fix problem finding module to import from contained subpackage name