package org.strategoxt.imp.runtime.services;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.spoofax.interpreter.terms.IStrategoString;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.strategoxt.imp.generator.construct_textual_change_4_0;
import org.strategoxt.imp.runtime.dynamicloading.BadDescriptorException;
import org.strategoxt.imp.runtime.dynamicloading.Descriptor;
import org.strategoxt.imp.runtime.dynamicloading.RefactoringFactory;
import org.strategoxt.imp.runtime.parser.SGLRParseController;
import org.strategoxt.imp.runtime.stratego.SourceAttachment;
import org.strategoxt.lang.Context;
import org.strategoxt.lang.Strategy;

/**
 * @author Oskar van Rest
 */
public class TextReplacer implements ITextReplacer {

	private Descriptor descriptor;
	private SGLRParseController controller;
	
	public TextReplacer(Descriptor descriptor, SGLRParseController controller) {
		this.descriptor = descriptor;
		this.controller = controller;
	}

	public void replaceText(IStrategoTerm resultTuple) {		
		IStrategoTerm textreplace = null;
		try {
			File file = SourceAttachment.getFile(controller.getCurrentAst());
			StrategoObserver observer = descriptor.createService(StrategoObserver.class, controller);
			textreplace = construct_textual_change_4_0.instance.invoke(
					observer.getRuntime().getCompiledContext(), 
					resultTuple, 
					createStrategy(RefactoringFactory.getPPStrategy(descriptor), file, observer),
					createStrategy(RefactoringFactory.getParenthesizeStrategy(descriptor), file, observer),
					createStrategy(RefactoringFactory.getOverrideReconstructionStrategy(descriptor), file, observer),
					createStrategy(RefactoringFactory.getResugarStrategy(descriptor), file, observer)
				);
		} catch (BadDescriptorException e) {
			e.printStackTrace();
		}
		
		writeToFile((IStrategoString) textreplace.getSubterm(0).getSubterm(2));
		queueAnalysisAffectedFile();
	}
	
	private Strategy createStrategy(final String sname, final File file, final StrategoObserver observer) {
		return new Strategy() {
			@Override
			public IStrategoTerm invoke(Context context, IStrategoTerm current) {
				if (sname!=null)
					return observer.invokeSilent(sname, current, file);
				return null;
			}
		};
	}
	
	// does this method exists already somewhere?
	private void writeToFile(IStrategoString term) {
		try {
			File file = SourceAttachment.getFile(controller.getCurrentAst());
			FileWriter fstream = new FileWriter(file);
			BufferedWriter out = new BufferedWriter(fstream);
			out.write(term.stringValue());
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		IResource resource = controller.getResource();
		try {
			resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}
	
	private void queueAnalysisAffectedFile() {
		IPath path = controller.getResource().getProjectRelativePath();
		IProject project = controller.getEditor().getProject().getRawProject();
		StrategoAnalysisQueueFactory.getInstance().queueAnalysis(path, project, true);
	}
}

@@ -60,336 +60,55 @@
 .io.
-BufferedWriter;%0D%0Aimport java.io.File;%0D%0Aimport java.io.FileWriter;%0D%0Aimport java.io.IOException;%0D%0A%0D%0Aimport org.eclipse.core.resources.IProject;%0D%0Aimport org.eclipse.core.resources.IResource;%0D%0Aimport org.eclipse.core.runtime.CoreException;%0D%0Aimport org.eclipse.core.runtime.IPath;%0D%0Aimport org.eclipse.core.runtime.NullProgressMonitor
+File;%0D%0A%0D%0Aimport org.eclipse.swt.widgets.Display
 ;%0D%0Ai
@@ -1069,46 +1069,8 @@
 ) %7B%09
-%09%0D%0A%09%09IStrategoTerm textreplace = null;
 %0D%0A%09%09
@@ -1243,16 +1243,30 @@
 r);%0D%0A%09%09%09
+IStrategoTerm 
 textrepl
@@ -1773,185 +1773,327 @@
 %0D%0A%09%09
-%7D catch (BadDescriptorException e) %7B%0D%0A%09%09%09e.printStackTrace();%0D%0A%09%09%7D%0D%0A%09%09%0D%0A%09%09writeToFile((IStrategoString) textreplace.getSubterm(0).getSubterm(2));%0D%0A%09%09queueAnalysisAffectedFile();
+%09final String result = ((IStrategoString) textreplace.getSubterm(0).getSubterm(2)).stringValue();%0D%0A%09%09%09%0D%0A%09%09%09Display.getDefault().syncExec(new Runnable() %7B%0D%0A%09%09%09%09public void run() %7B%0D%0A%09%09%09%09%09controller.getEditor().getDocument().set(result);%0D%0A%09%09%09%09%7D%0D%0A%09%09%09%7D);%0D%0A%09%09%7D catch (BadDescriptorException e) %7B%0D%0A%09%09%09e.printStackTrace();%0D%0A%09%09%7D
 %0D%0A%09%7D
@@ -2436,880 +2436,7 @@
 %09%7D%0D%0A
-%09%0D%0A%09// does this method exists already somewhere?%0D%0A%09private void writeToFile(IStrategoString term) %7B%0D%0A%09%09try %7B%0D%0A%09%09%09File file = SourceAttachment.getFile(controller.getCurrentAst());%0D%0A%09%09%09FileWriter fstream = new FileWriter(file);%0D%0A%09%09%09BufferedWriter out = new BufferedWriter(fstream);%0D%0A%09%09%09out.write(term.stringValue());%0D%0A%09%09%09out.close();%0D%0A%09%09%7D catch (IOException e) %7B%0D%0A%09%09%09e.printStackTrace();%0D%0A%09%09%7D%0D%0A%09%09%0D%0A%09%09IResource resource = controller.getResource();%0D%0A%09%09try %7B%0D%0A%09%09%09resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());%0D%0A%09%09%7D catch (CoreException e) %7B%0D%0A%09%09%09e.printStackTrace();%0D%0A%09%09%7D%0D%0A%09%7D%0D%0A%09%0D%0A%09private void queueAnalysisAffectedFile() %7B%0D%0A%09%09IPath path = controller.getResource().getProjectRelativePath();%0D%0A%09%09IProject project = controller.getEditor().getProject().getRawProject();%0D%0A%09%09StrategoAnalysisQueueFactory.getInstance().queueAnalysis(path, project, true);%0D%0A%09%7D%0D%0A
 %7D%0D%0A

replace document content instead of file.