/**
*
*/
package net.sf.eclipsefp.haskell.ui.internal.resolve;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import net.sf.eclipsefp.haskell.browser.util.ImageCache;
import net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin;
import net.sf.eclipsefp.haskell.core.cabal.CabalPackageVersion;
import net.sf.eclipsefp.haskell.core.cabal.CabalPackageVersion.Restriction;
import net.sf.eclipsefp.haskell.core.cabalmodel.CabalSyntax;
import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescription;
import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescriptionLoader;
import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescriptionStanza;
import net.sf.eclipsefp.haskell.core.cabalmodel.RealValuePosition;
import net.sf.eclipsefp.haskell.core.util.ResourceUtil;
import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin;
import net.sf.eclipsefp.haskell.ui.internal.backend.CabalPackageHelper;
import net.sf.eclipsefp.haskell.ui.internal.preferences.editor.IEditorPreferenceNames;
import net.sf.eclipsefp.haskell.ui.internal.util.UITexts;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProvider;
/**
* Add a package to the build-depends of cabal stanzas
* @author JP Moresmau
*
*/
public class AddPackageDependencyProposal implements ICompletionProposal {
private String value;
private final IMarker marker;
public AddPackageDependencyProposal(final String value, final IMarker marker) {
this.value = value;
this.marker = marker;
}
public AddPackageDependencyProposal(final String value) {
this.value = value;
this.marker = null;
}
@Override
public void apply( final IDocument document ) {
apply((IFile)marker.getResource());
}
public void apply(final IFile res) {
IFile f=BuildWrapperPlugin.getCabalFile( res.getProject() );
IDocumentProvider prov=new TextFileDocumentProvider();
try {
prov.connect( f );
IDocument doc=prov.getDocument( f );
PackageDescription pd=PackageDescriptionLoader.load( f );
String fullVersion=getValue();
String v=CabalPackageHelper.getInstance().getLastInstalledVersion( getValue());
if (v!=null){
String s=HaskellUIPlugin.getEditorPreferenceStore().getString( IEditorPreferenceNames.EDITOR_FIXES_PACKAGE_RESTRICTION );
Restriction r=Restriction.valueOf( s );
fullVersion=CabalPackageVersion.getRange( getValue(), v, r );
//fullVersion=getValue()+ " "+ CabalPackageVersion.getMajorRange( v );
}
// find applicable stanzas if any, to not modify all of the cabal stanzas
Set<PackageDescriptionStanza> apps=ResourceUtil.getApplicableStanzas( new IFile[]{res} );
Set<String> appNames=new HashSet<>();
for (PackageDescriptionStanza pds:apps){
Collection<String> pkgs=pds.getDependentPackages();
// some stanzas may already have the dependency
if(!pkgs.contains( getValue() )){
for (String s:pkgs){
if (s.startsWith( getValue()+" " )){
continue;
}
}
appNames.add(pds.toTypeName());
}
}
value=fullVersion;
int length=pd.getStanzas().size();
for (int a=0;a<length;a++){
PackageDescriptionStanza pds=pd.getStanzas().get(a);
//CabalSyntax cs=pds.getType();
if (appNames.isEmpty() || appNames.contains( pds.toTypeName() )){
if (pds.isSourceStanza()){
RealValuePosition rvp=update(pds);
if (rvp!=null){
rvp.updateDocument( doc );
pd=PackageDescriptionLoader.load( doc.get() );
}
}
}
}
prov.saveDocument( new NullProgressMonitor(), f, doc, true );
} catch (Exception ce){
HaskellUIPlugin.log( ce );
}
}
protected RealValuePosition update(final PackageDescriptionStanza pds){
return pds.addToPropertyList( getCabalField(), getValue() );
}
protected CabalSyntax getCabalField(){
return CabalSyntax.FIELD_BUILD_DEPENDS;
}
/**
* @return the value
*/
public String getValue() {
return value;
}
@Override
public Point getSelection( final IDocument document ) {
return null;
}
@Override
public String getAdditionalProposalInfo() {
return null;
}
@Override
public String getDisplayString() {
return NLS.bind( UITexts.resolve_addpackage, value );
}
@Override
public Image getImage() {
return ImageCache.PACKAGE;
}
@Override
public IContextInformation getContextInformation() {
return null;
}
}