package org.strategoxt.imp.runtime.stratego;

import java.io.File;

import org.eclipse.core.resources.IResource;
import org.spoofax.interpreter.core.IContext;
import org.spoofax.interpreter.core.InterpreterException;
import org.spoofax.interpreter.core.Tools;
import org.spoofax.interpreter.library.AbstractPrimitive;
import org.spoofax.interpreter.library.IOAgent;
import org.spoofax.interpreter.library.ssl.SSLLibrary;
import org.spoofax.interpreter.stratego.Strategy;
import org.spoofax.interpreter.terms.IStrategoString;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.strategoxt.imp.runtime.Environment;
import org.strategoxt.imp.runtime.services.StrategoAnalysisJob;
import org.strategoxt.imp.runtime.services.StrategoObserver;

public class SetOnlyMarkersPrimitive extends AbstractPrimitive {

	public SetOnlyMarkersPrimitive() {
		super("SSL_EXT_set_only_markers", 0, 1);
	}

	@Override
	public boolean call(IContext env, Strategy[] svars, IStrategoTerm[] tvars)
			throws InterpreterException {
		
		IOAgent agent = SSLLibrary.instance(env).getIOAgent();
		if (!(agent instanceof EditorIOAgent)) 
			return false;
	
		IResource resource = getResource(tvars);
		if (resource == null)
			return false;
	
		
		StrategoAnalysisJob job = ((EditorIOAgent)agent).getJob();

		StrategoObserver observer = job.getObserver();

		// HACK: presentToUser runs a feedback postprocess strategy which calls primitives witch set env.current()
		// (nested primitives...)
		IStrategoTerm previousTerm = env.current();
		observer.updateMarkers(resource, env.current());
		env.setCurrent(previousTerm);

		return true;
	}

	/**
	 * @param tvars
	 * @param resource
	 * @return
	 */
	private static IResource getResource(IStrategoTerm[] tvars) {
		IResource resource = null;
		if( tvars[0] instanceof IStrategoString){
			// HACK : often Source Attachment is missing in the root node.
			// Hence, providing the path to the resource instead of getting 
			// it from the SourceAttachment 
			try{
				resource = EditorIOAgent.getResource(new File(Tools.asJavaString(tvars[0])));
			}catch(Exception e){
				Environment.logException("Invalid resource path is provided : "+ tvars[0] , e);
			}
		}
		else{
			resource = SourceAttachment.getResource(tvars[0]);
		}
		return resource;
	}

}

@@ -1221,19 +1221,80 @@
 se;%0A%09%0A%09%09
-%0A%09%09
+final EditorIOAgent editorAgent = (EditorIOAgent)agent;%0A%09%09final 
 Stratego
@@ -1315,44 +1315,238 @@
 b = 
-((E
+e
 ditor
-IO
 Agent
-)agent).getJob();%0A%0A%09%09
+.getJob();%0A%09%09// HACK: warn if no job is found, and do nothing..%0A%09%09if(job == null) %7B%0A%09%09    Environment.logWarning(%22Could not set messages for %22 + resource + %22, no running job was found.%22);%0A%09%09    return true;%0A%09%09%7D%0A%09%09final 
 Stra

Work around NPE in SetOnlyMarkersPrimitive, a proper fix does not seem to be possible with this architecture.