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

import static com.redhat.ceylon.eclipse.util.EditorUtil.getCurrentEditor;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.StringWriter;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ltk.core.refactoring.DocumentChange;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.text.edits.ReplaceEdit;

import ceylon.tool.converter.java2ceylon.Java8Lexer;
import ceylon.tool.converter.java2ceylon.Java8Parser;
import ceylon.tool.converter.java2ceylon.JavaToCeylonConverter;
import com.redhat.ceylon.eclipse.code.refactor.AbstractHandler;
import com.redhat.ceylon.eclipse.util.EditorUtil;

public class PasteAsCeylonHandler extends AbstractHandler {

	@Override
	public Object execute(ExecutionEvent arg0) throws ExecutionException {
		String ceylonCode = "<error>";
		Clipboard cb = new Clipboard(null);
		String javaCode = (String) cb.getContents(TextTransfer.getInstance());

		try {
			ceylonCode = transformJavaToCeylon(javaCode);
		} catch (IOException e) {
			e.printStackTrace();
		}

		insertTextInEditor(ceylonCode);

		return null;
	}

	private String transformJavaToCeylon(String javaCode) throws IOException {
		ANTLRInputStream input = new ANTLRInputStream(javaCode);
		Java8Lexer lexer = new Java8Lexer(input);
		CommonTokenStream tokens = new CommonTokenStream(lexer);
		Java8Parser parser = new Java8Parser(tokens);
		ParserRuleContext tree = parser.compilationUnit();

		StringWriter out = new StringWriter();
		BufferedWriter bw = new BufferedWriter(out);
		JavaToCeylonConverter converter = new JavaToCeylonConverter(bw);

		ParseTreeWalker.DEFAULT.walk(converter, tree);
		converter.close();

		String ceylonCode = out.toString();

		if (ceylonCode.equals("")) {
			return javaCode;
		}

		return ceylonCode;
	}

	private void insertTextInEditor(String ceylonCode) {
		CeylonEditor editor = (CeylonEditor) getCurrentEditor();
		IDocument doc = editor.getCeylonSourceViewer().getDocument();

		int offset = 0;

		offset = EditorUtil.getSelection(editor).getOffset();

		DocumentChange change = new DocumentChange("Paste Java as Ceylon", doc);
		change.setEdit(new ReplaceEdit(offset, 0, ceylonCode));

		try {
			change.perform(new NullProgressMonitor());
		} catch (CoreException e) {
			e.printStackTrace();
		}

		FormatAction.format(editor.getParseController(), doc, EditorUtil.getSelection(editor), false,
				editor.getSelectionProvider());
	}

	@Override
	protected boolean isEnabled(CeylonEditor editor) {
		return true;
	}

}

@@ -536,32 +536,73 @@
 .CoreException;%0A
+import org.eclipse.core.runtime.IStatus;%0A
 import org.eclip
@@ -638,16 +638,16 @@
 onitor;%0A
-
 import o
@@ -1089,24 +1089,74 @@
 actHandler;%0A
+import com.redhat.ceylon.eclipse.ui.CeylonPlugin;%0A
 import com.r
@@ -1571,34 +1571,82 @@
 e) %7B%0A%09%09%09
-e.printStackTrace(
+CeylonPlugin.log(IStatus.ERROR, %22Could not transform Java code%22, e
 );%0A%09%09%7D%0A%0A
@@ -2084,55 +2084,8 @@
 ();%0A
-%09%09BufferedWriter bw = new BufferedWriter(out);%0A
 %09%09Ja
@@ -2146,65 +2146,40 @@
 ter(
-bw
+out, true, true
 );%0A
-%0A
 %09%09
-ParseTreeWalker.DEFAULT.walk(converter, tree);%0A%09%09
+tree.accept(
 conv
@@ -2187,15 +2187,8 @@
 rter
-.close(
 );%0A%0A
@@ -2786,26 +2786,77 @@
 %0A%09%09%09
-e.printStackTrace(
+CeylonPlugin.log(IStatus.ERROR, %22Could not paste transformed code%22, e
 );%0A%09

Make PasteAsCeylonHandler use the new converter