package edu.fichte.pbi.ide.commands;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;
import org.osgi.framework.Bundle;

import edu.fichte.pbi.ide.Activator;
import edu.fichte.pbi.ide.editors.ConfigEditor;
import edu.fichte.pbi.ide.editors.PBIEditor;
import edu.fichte.pbi.ide.views.ConsoleView;
import edu.fichte.pbi.ide.views.HelpView;

public class ContentAssistCommandHandler implements IHandler, IHandler2 {

	private static Map<String, String> commands = null;

	@Override
	public void setEnabled(Object evaluationContext) {
		// TODO Auto-generated method stub

	}

	@Override
	public void addHandlerListener(IHandlerListener handlerListener) {
		// TODO Auto-generated method stub

	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub

	}

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);

		if (activeEditor instanceof PBIEditor) {
			PBIEditor pbi = (PBIEditor) activeEditor;
			StyledText editor = pbi.getText();
			Point selectionRange = editor.getSelection();
			String text = editor.getText();
			int from;
			int to = selectionRange.y;
			for (from = to - 1; from > 0; from--) {
				if (text.charAt(from) == ' ')
					return null;
				if (text.charAt(from) == '\n')
					break;
			}
			try {
				String content = text.substring(from, to).trim();
				content = content.toUpperCase();
				execute: {
					boolean defined = false;
					String result = null;
					if (commands == null || ConfigEditor.hasChanged) {
						initCommands(event);
					}
					for (String cmd : commands.keySet()) {
						cmd = cmd.toUpperCase();
						if (cmd.startsWith(content) && !defined) {
							defined = true;
							result = cmd;
						} else if (cmd.startsWith(content) && defined) {
							break execute;
						}
					}
					String replacement = commands.get(result);
					if (replacement != null) {
						String left = text.substring(0, from + 1);
						String right = text.substring(from + content.length()
								+ 1);
						String newText = left + replacement + right;
						editor.setText(newText);
						to = from + replacement.length() + 1;
						editor.setSelection(new Point(to, to));
					}
				}
			} catch (ArrayIndexOutOfBoundsException e) {
				e.printStackTrace();
			}

		}
		return null;
	}

	public static void initCommands(ExecutionEvent event) {
		commands = new HashMap<>();
		Bundle bundle = Activator.getDefault().getBundle();
		File targetRoot = bundle.getDataFile("");
		File file = new File(targetRoot, "config/ca.cfg");
		IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
		if (!file.canRead()) {
			// must copy the html from the bundle .jar to the data file location
			HelpView.copyPathFromBundleToFSRecursive(bundle, "config",
					targetRoot);
		}

		Scanner scanner = null;
		try {
			scanner = new Scanner(file);
			String line;
			while (scanner.hasNextLine()) {
				line = scanner.nextLine().trim();
				if (line.startsWith("##") || line.isEmpty()) {
					continue;
				} else if (line.contains("->")) {
					String[] split = line.split("->");
					if (split.length != 2) {
						scanner.close();

						throw new IllegalArgumentException();
					}
					commands.put(split[0].trim(),
							split[1].trim().replace("/CR", "\n"));
				} else {
					scanner.close();
					throw new IllegalArgumentException();
				}
			}
			scanner.close();
		} catch (FileNotFoundException | IllegalArgumentException e) {
			e.printStackTrace();
			try {
				((ConsoleView) window.getActivePage().showView(ConsoleView.ID))
						.print("[Error, content assist]Couldn't read the configuration file\n");
			} catch (PartInitException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}

	}

	@Override
	public boolean isEnabled() {
		return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
				.getActivePage().getActiveEditor() instanceof PBIEditor;
	}

	@Override
	public boolean isHandled() {
		return true;
	}

	@Override
	public void removeHandlerListener(IHandlerListener handlerListener) {
		// TODO Auto-generated method stub

	}

}
