/*=============================================================================#
 # Copyright (c) 2008, 2021 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.RCore;
import org.eclipse.statet.r.core.RCoreAccess;
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 RCoreAccess 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);
	}
	
}
