/*=============================================================================#
 # Copyright (c) 2008, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.r.debug.ui.launcher;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.jcommons.ts.core.ToolService;

import org.eclipse.statet.ecommons.runtime.core.util.StatusUtils;
import org.eclipse.statet.ecommons.text.IndentUtil;
import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.r.debug.ui.RLaunchingMessages;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.util.LTKWorkbenchUIUtil;
import org.eclipse.statet.nico.core.runtime.ConsoleRunnable;
import org.eclipse.statet.nico.core.runtime.IRequireSynch;
import org.eclipse.statet.nico.core.runtime.SubmitType;
import org.eclipse.statet.nico.core.runtime.ToolController;
import org.eclipse.statet.nico.ui.NicoUI;
import org.eclipse.statet.nico.ui.NicoUITools;
import org.eclipse.statet.r.console.core.IRBasicAdapter;
import org.eclipse.statet.r.console.core.RConsoleTool;
import org.eclipse.statet.r.console.core.RWorkspace;
import org.eclipse.statet.r.core.IRCoreAccess;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.RUtil;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.r.ui.editors.IRSourceEditor;


/**
 * 
 */
public class SubmitSelectionAndPasteOutputHandler extends AbstractHandler {
	
	
	private static class R implements ConsoleRunnable, Runnable {
		
		private ISourceEditor fEditor;
		private IDocument fDocument;
		private String[] fLines;
		private Position fPosition;
		private StringBuilder fOutput;
		
		
		R(final ISourceEditor editor) {
			fEditor = editor;
		}
		
		private boolean setupSource(final ITextSelection selection) {
			final SourceViewer viewer = fEditor.getViewer();
			fDocument = viewer.getDocument();
			try {
				if (selection.getLength() > 0) {
					final ArrayList<String> lines= new ArrayList<>(0);
					TextUtil.addLines(fDocument, selection.getOffset(), selection.getLength(), lines);
					fLines = lines.toArray(new String[lines.size()]);
					
					final int start = selection.getOffset();
					int end = start + selection.getLength();
					final char c = fDocument.getChar(end-1);
					if (c == '\n') {
						end--;
						if (end > 0 && fDocument.getChar(end-1) == '\r') {
							end--;
						}
					}
					else if (c == '\r') {
						end--;
					}
					fPosition = new Position(start, end - start);
				}
				else {
					final IRegion line = fDocument.getLineInformationOfOffset(selection.getOffset());
					fLines = new String[] { fDocument.get(line.getOffset(), line.getLength()) };
					fPosition = new Position(line.getOffset(), line.getLength());
				}
				fDocument.addPosition(fPosition);
				return true;
			}
			catch (final BadLocationException e) {
				StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, -1, "An error occurred preparing Run and Paste Output", e)); //$NON-NLS-1$
				return false;
			}
		}
		
		public void dispose() {
			if (fDocument != null && fPosition != null) {
				fDocument.removePosition(fPosition);
			}
			fEditor = null;
			fDocument = null;
			fPosition = null;
			fOutput = null;
			fLines = null;
		}
		
		@Override
		public String getTypeId() {
			return "editor/run-and-paste"; //$NON-NLS-1$
		}
		
		@Override
		public String getLabel() {
			return RLaunchingMessages.SubmitCodeAndPasteOutput_RTask_label;
		}
		
		@Override
		public SubmitType getSubmitType() {
			return SubmitType.EDITOR;
		}
		
		@Override
		public boolean canRunIn(final Tool tool) {
			return (tool.isProvidingFeatureSet(RConsoleTool.R_BASIC_FEATURESET_ID));
		}
		
		@Override
		public boolean changed(final int event, final Tool process) {
			switch (event) {
			case REMOVING_FROM:
			case BEING_ABANDONED:
				UIAccess.getDisplay().asyncExec(new Runnable() {
					@Override
					public void run() {
						dispose();
					}
				});
				break;
			}
			return true;
		}
		
		@Override
		public void run(final ToolService service,
				final ProgressMonitor m) throws StatusException {
			final IRBasicAdapter r = (IRBasicAdapter) service;
			fOutput = new StringBuilder(200);
			final IStreamListener listener = new IStreamListener() {
				@Override
				public void streamAppended(final String text, final IStreamMonitor monitor) {
					fOutput.append(text);
				}
			};
			final ToolController controller = r.getController();
			r.briefAboutToChange();
			try {
				controller.getStreams().getOutputStreamMonitor().addListener(listener);
				controller.getStreams().getErrorStreamMonitor().addListener(listener);
				for (int i = 0; i < fLines.length; i++) {
					if (m.isCanceled()) {
						return;
					}
					m.beginSubTask(fLines[i]);
					r.submitToConsole(fLines[i], m);
				}
				if (r instanceof IRequireSynch) {
					final Pattern pattern = ((IRequireSynch) r).synch(m);
					if (pattern != null) {
						final Matcher matcher = pattern.matcher(fOutput);
						int idx = -1;
						while (matcher.find()) {
							idx = matcher.start();
						}
						if (idx >= 0) {
							fOutput.delete(idx, fOutput.length());
						}
					}
				}
			}
			finally {
				r.briefChanged(RWorkspace.REFRESH_AUTO);
				controller.getStreams().getOutputStreamMonitor().removeListener(listener);
				controller.getStreams().getErrorStreamMonitor().removeListener(listener);
				UIAccess.getDisplay().asyncExec(this);
			}
		}
		
		protected IRCoreAccess getRCoreAccess() {
			final ISourceEditor editor= fEditor;
			return (editor instanceof IRSourceEditor) ?
					((IRSourceEditor) editor).getRCoreAccess() :
					RCore.WORKBENCH_ACCESS;
		}
		
		@Override
		public void run() {
			// After R in display
			final SourceViewer viewer = fEditor.getViewer();
			if (!UIAccess.isOkToUse(viewer)
					|| (viewer.getDocument() != fDocument)
					|| fPosition.isDeleted()) {
				return;
			}
			
			IWorkbenchSiteProgressService progressService = null;
			final ISourceEditor editor = fEditor.getAdapter(ISourceEditor.class);
			if (editor != null) {
				final IServiceLocator serviceLocator = editor.getServiceLocator();
				if (serviceLocator != null) {
					progressService = serviceLocator.getService(IWorkbenchSiteProgressService.class);
				}
			}
			if (progressService != null) {
				progressService.incrementBusy();
			}
			
			try {
				final IndentUtil util= new IndentUtil(fDocument, getRCoreAccess().getRCodeStyle());
				
				final int indent = util.getMultilineIndentColumn(fDocument.getLineOfOffset(fPosition.getOffset()),
						fDocument.getLineOfOffset(fPosition.getOffset() + fPosition.getLength()));
				final String delimiter = TextUtilities.getDefaultLineDelimiter(fDocument);
				final String prefix = delimiter + util.createIndentString(indent) + "# "; //$NON-NLS-1$
				
				final String[] lines = RUtil.LINE_SEPARATOR_PATTERN.split(fOutput);
				final int size = fOutput.length() + lines.length*(prefix.length()-1) + 2;
				fOutput.setLength(0);
				fOutput.ensureCapacity(size);
				for (int i = 0; i < lines.length; i++) {
					fOutput.append(prefix);
					fOutput.append(lines[i]);
				}
				fOutput.append(delimiter);
				final int pos = fPosition.getOffset()+fPosition.getLength();
				fDocument.replace(pos, 0, fOutput.toString());
				viewer.revealRange(pos, fOutput.length());
				if (progressService != null) {
					progressService.warnOfContentChange();
				}
			}
			catch (final BadLocationException e) {
				StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, -1,
						RLaunchingMessages.SubmitCodeAndPasteOutput_error_WhenPasting_message, e),
						StatusManager.LOG | StatusManager.SHOW);
			}
			finally {
				dispose();
				if (progressService != null) {
					progressService.decrementBusy();
				}
			}
			
		}
	}
	
	
	public SubmitSelectionAndPasteOutputHandler() {
	}
	
	
	@Override
	public Object execute(final ExecutionEvent event) throws ExecutionException {
		final IWorkbenchPart workbenchPart = HandlerUtil.getActivePart(event);
		final ISourceEditor editor = workbenchPart.getAdapter(ISourceEditor.class);
		if (editor != null) {
			if (!editor.isEditable(true)) {
				cancel(null, new Status(IStatus.ERROR, RUI.BUNDLE_ID,
						RLaunchingMessages.SubmitCodeAndPasteOutput_info_WriteProtected_status), event);
				return null;
			}
			final SourceViewer viewer = editor.getViewer();
			final ITextSelection selection = (ITextSelection) viewer.getSelection();
			final R r = new R(editor);
			if (!r.setupSource(selection)) {
				cancel(r, new Status(IStatus.ERROR, RUI.BUNDLE_ID,
						RLaunchingMessages.SubmitCodeAndPasteOutput_error_Unspecific_status), null);
				return null;
			}
			final Tool tool= NicoUI.getToolRegistry().getActiveToolSession(UIAccess.getActiveWorkbenchPage(true))
					.getTool();
			try {
				NicoUITools.accessTool(RConsoleTool.TYPE, tool);
			}
			catch (final CoreException e) {
				cancel(r, e.getStatus(), event);
				return null;
			}
			final org.eclipse.statet.jcommons.status.Status status= tool.getQueue().add(r);
			if (status.getSeverity() >= Status.ERROR) {
				cancel(r, StatusUtils.convert(status), event);
			}
			return null;
		}
		
		LaunchShortcutUtil.handleUnsupportedExecution(event);
		return null;
	}
	
	private void cancel(final R r, final IStatus status, final ExecutionEvent executionEvent) {
		if (r != null) {
			r.dispose();
		}
		LTKWorkbenchUIUtil.indicateStatus(status, executionEvent);
	}
	
}
