/*=============================================================================#
 # 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.r.launching;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.variables.IDynamicVariable;
import org.eclipse.core.variables.IStringVariable;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.status.eplatform.EStatusUtils;
import org.eclipse.statet.jcommons.ts.core.ToolRunnable;

import org.eclipse.statet.ecommons.preferences.core.Preference.BooleanPref;
import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils;
import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.ecommons.variables.core.DynamicVariable;
import org.eclipse.statet.ecommons.variables.core.StringVariable;
import org.eclipse.statet.ecommons.variables.core.VariableText;
import org.eclipse.statet.ecommons.variables.core.VariableText.LocationProcessor;

import org.eclipse.statet.internal.r.debug.ui.RControllerCodeLaunchConnector;
import org.eclipse.statet.internal.r.debug.ui.RLaunchingMessages;
import org.eclipse.statet.internal.r.debug.ui.launcher.RCodeLaunchRegistry;
import org.eclipse.statet.internal.r.debug.ui.launcher.RCodeLaunchRegistry.ContentHandler.FileCommand;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.ltk.model.core.element.WorkspaceSourceUnit;
import org.eclipse.statet.nico.core.runtime.ToolController;
import org.eclipse.statet.nico.core.runtime.ToolWorkspace;
import org.eclipse.statet.r.console.core.AbstractRController;
import org.eclipse.statet.r.core.RUtil;
import org.eclipse.statet.r.core.model.RLangSourceElement;
import org.eclipse.statet.r.core.model.RSourceUnit;
import org.eclipse.statet.r.core.model.RWorkspaceSourceUnit;
import org.eclipse.statet.r.core.rsource.ast.GenericVisitor;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.nico.IRModelSrcref;
import org.eclipse.statet.r.ui.RUI;


/**
 * Provides methods to submit code to R
 * 
 * The methods use the code launch connector selected in the preferences
 * and therefore it supports external consoles too
 * (in contrast to direct usage of new {@link AbstractRController}).
 */
public final class RCodeLaunching {
	
	
	public static final String SUBMIT_SELECTION_COMMAND_ID = "org.eclipse.statet.r.commands.SubmitSelectionToR"; //$NON-NLS-1$
	
	public static final String SUBMIT_SELECTION_GOTOCONSOLE_COMMAND_ID = "org.eclipse.statet.r.commands.SubmitSelectionToR_GotoConsole"; //$NON-NLS-1$
	
	public static final String SUBMIT_SELECTION_PASTEOUTPUT_COMMAND_ID = "org.eclipse.statet.r.commands.SubmitSelectionToR_PasteOutput"; //$NON-NLS-1$
	
	public static final String SUBMIT_UPTO_SELECTION_COMMAND_ID = "org.eclipse.statet.r.commands.SubmitUptoSelectionToR"; //$NON-NLS-1$
	
	public static final String SUBMIT_FILEVIACOMMAND_COMMAND_ID = "org.eclipse.statet.r.commands.SubmitFileToRViaCommand"; //$NON-NLS-1$
	
	public static final String SUBMIT_FILEVIACOMMAND_GOTOCONSOLE_COMMAND_ID = "org.eclipse.statet.r.commands.SubmitFileToRViaCommand_GotoConsole"; //$NON-NLS-1$
	
	
	public static final String FILE_COMMAND_ID_PARAMTER_ID = "fileCommandId"; //$NON-NLS-1$
	
	
	private static final IStringVariable FILE_NAME_VARIABLE = new StringVariable("resource_loc", "The complete path of the source file"); //$NON-NLS-1$
	private static final IStringVariable FILE_ENCODING_VARIABLE = new StringVariable("resource_encoding", "The encoding of the source file"); //$NON-NLS-1$
	private static final IStringVariable ECHO_ENABLED_VARIABLE = new StringVariable("echo", "If echo is enabled"); //$NON-NLS-1$
	
	private static final IStatus STATUS_PROMPTER = new org.eclipse.core.runtime.Status(IStatus.INFO, IDebugUIConstants.PLUGIN_ID, 200, "", null); //$NON-NLS-1$
	private static final IStatus STATUS_SAVE = new org.eclipse.core.runtime.Status(IStatus.INFO, DebugPlugin.getUniqueIdentifier(), 222, "", null); //$NON-NLS-1$
	
	
	public static class SourceRegion implements IRModelSrcref, IAdaptable {
		
		private static final String MARKER_TYPE = "org.eclipse.core.resources.marker";
		
		private static class ElementSearcher extends GenericVisitor {
			
			
			private List<RLangSourceElement> fList;
			
			
			@Override
			public void visitNode(final RAstNode node) throws InvocationTargetException {
				final List<Object> attachments= node.getAttachments();
				for (final Object attachment : attachments) {
					if (attachment instanceof RLangSourceElement) {
						if (fList == null) {
							fList= new ArrayList<>();
						}
						fList.add((RLangSourceElement) attachment);
					}
				}
				if (fList == null) {
					super.visitNode(node);
				}
			}
			
		}
		
		
		private final RSourceUnit fSourceUnit;
		private RAstNode fNode;
		private List<RLangSourceElement> fElements;
		
		private final AbstractDocument fDocument;
		
		private int fBeginOffset = -1;
		private int fBeginLine = -1;
		private int fBeginColumn = -1;
		private int fEndOffset = -1;
		private int fEndLine = -1;
		private int fEndColumn = -1;
		
		private String fCode;
		
		private IMarker fMarker;
		
		
		public SourceRegion(final RSourceUnit file, final AbstractDocument document) {
			fSourceUnit = file;
			fDocument = document;
		}
		
		
		@Override
		public RSourceUnit getFile() {
			return fSourceUnit;
		}
		
		public void setNode(final RAstNode node) {
			fNode = node;
		}
		
		@Override
		public List<RLangSourceElement> getElements() {
			if (fElements == null) {
				if (fNode != null) {
					final ElementSearcher searcher = new ElementSearcher();
					try {
						searcher.visitNode(fNode);
						fElements = searcher.fList;
					}
					catch (final InvocationTargetException e) {}
				}
				if (fElements == null) {
					fElements = Collections.emptyList();
				}
			}
			return fElements;
		}
		
		
		public void setCode(final String code) {
			fCode = code;
		}
		
		public void setBegin(final int offset) throws BadLocationException {
			fBeginOffset = offset;
			fBeginLine = fDocument.getLineOfOffset(fBeginOffset);
			fBeginColumn = TextUtil.getColumn(fDocument, fBeginOffset, fBeginLine, 8);
		}
		
		@Override
		public boolean hasBeginDetail() {
			return (fBeginLine >= 0 && fBeginColumn >= 0);
		}
		
		@Override
		public int getOffset() {
			return fBeginOffset;
		}
		
		@Override
		public int getFirstLine() {
			return fBeginLine;
		}
		
		@Override
		public int getFirstColumn() {
			return fBeginColumn;
		}
		
		public void setEnd(final int offset) throws BadLocationException {
			fEndOffset = offset;
			fEndLine = fDocument.getLineOfOffset(fEndOffset);
			fEndColumn = TextUtil.getColumn(fDocument, fEndOffset-1, fEndLine, 8);
		}
		
		@Override
		public boolean hasEndDetail() {
			return (fEndLine >= 0 && fEndColumn >= 0);
		}
		
		@Override
		public int getLength() {
			return fEndOffset-fBeginOffset;
		}
		
		@Override
		public int getLastLine() {
			return fEndLine;
		}
		
		@Override
		public int getLastColumn() {
			return fEndColumn;
		}
		
		
		void installMarker() {
			if (fSourceUnit instanceof RWorkspaceSourceUnit) {
				final IResource resource = ((RWorkspaceSourceUnit) fSourceUnit).getResource();
				try {
					fMarker = resource.createMarker(MARKER_TYPE);
					fMarker.setAttribute(IMarker.CHAR_START, fBeginOffset);
					fMarker.setAttribute(IMarker.CHAR_END, fEndOffset);
				}
				catch (final CoreException e) {
					StatusManager.getManager().handle(new org.eclipse.core.runtime.Status(IStatus.ERROR, RUI.BUNDLE_ID, 0,
							"An error occurred when creating code position marker.", e));
				}
			}
		}
		
		void disposeMarker() {
			if (this.fMarker != null) {
				try {
					this.fMarker.delete();
					this.fMarker = null;
				}
				catch (final CoreException e) {
					StatusManager.getManager().handle(new org.eclipse.core.runtime.Status(IStatus.ERROR, RUI.BUNDLE_ID, 0,
							"An error occurred when removing code position marker.", e));
				}
			}
		}
		
		@Override
		public <T> T getAdapter(final Class<T> adapterType) {
			if (adapterType == IMarker.class) {
				return (T) this.fMarker;
			}
			return null;
		}
		
	}
	
	
	public static void gotoRConsole() throws CoreException {
		final IRCodeSubmitConnector connector = RCodeLaunchRegistry.getDefault().getConnector();
		
		connector.gotoConsole();
	}
	
	public static String getFileCommand(final String id) {
		final FileCommand fileCommand = RCodeLaunchRegistry.getDefault().getFileCommand(id);
		if (fileCommand != null) {
			return fileCommand.getCurrentCommand();
		}
		return null;
	}
	
	public static String getPreferredFileCommand(final String contentType) {
		final FileCommand fileCommand = RCodeLaunchRegistry.getDefault().getContentFileCommand(contentType);
		return fileCommand.getCurrentCommand();
	}
	
	public static ICodeSubmitContentHandler getCodeSubmitContentHandler(final String contentType) {
		return RCodeLaunchRegistry.getDefault().getContentHandler(contentType);
	}
	
	
	/**
	 * Runs a file related command in R.
	 * Use this method only, if you don't have an IFile or IPath object for your file
	 * (e.g. file on webserver).
	 * <p>
	 * The pattern ${file} in command string is replaced by the path of
	 * the specified file.</p>
	 * 
	 * @param command the command, (at moment) should be single line.
	 * @param file the file.
	 * @throws CoreException if running failed.
	 */
	public static void runFileUsingCommand(final String command, final URI fileURI,
			final SourceUnit su, final String encoding, final boolean gotoConsole) throws CoreException {
		if (su instanceof WorkspaceSourceUnit && su.getResource() instanceof IFile) {
			final IFile file = (IFile) ((WorkspaceSourceUnit) su).getResource();
			
			// save files
			final IProject project = file.getProject();
			if (project != null) {
				final IProject[] referencedProjects = project.getReferencedProjects();
				final IProject[] allProjects = new IProject[referencedProjects.length+1];
				allProjects[0] = project;
				System.arraycopy(referencedProjects, 0, allProjects, 1, referencedProjects.length);
				if (!saveBeforeLaunch(allProjects)) {
					return;
				}
			}
		}
		
		final IRCodeSubmitConnector connector = RCodeLaunchRegistry.getDefault().getConnector();
		IFileStore fileStore = null;
		try {
			fileStore = EFS.getStore(fileURI);
		}
		catch (final CoreException e) {
			fileStore = null;
		}
		
		if (fileStore != null && connector instanceof RControllerCodeLaunchConnector) {
			final IFileStore store = fileStore;
			((RControllerCodeLaunchConnector) connector).submit(new RControllerCodeLaunchConnector.CommandsCreator() {
				@Override
				public Status submitTo(final ToolController controller) {
					final ToolWorkspace workspace = controller.getWorkspaceData();
					try {
						final String path = workspace.toToolPath(store);
						final String code = resolveVariables(command, path, encoding);
						final ToolRunnable runnable = new SubmitFileViaCommandRunnable(
								PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE),
								"Run '" + store.toString() + "'", // TODO custom image and label
								code, su );
						final Status status = controller.getTool().getQueue().add(runnable);
						if (status.getSeverity() != Status.OK) {
							runnable.changed(ToolRunnable.BEING_ABANDONED, null);
						}
						return status;
					}
					catch (final StatusException e) {
						return e.getStatus();
					}
					catch (final CoreException e) {
						return EStatusUtils.convert(e.getStatus());
					}
				}
			}, gotoConsole);
		}
		else {
			String path = null;
			try {
				if (EFS.getLocalFileSystem().equals(EFS.getFileSystem(fileURI.getScheme()))) {
					path = EFS.getLocalFileSystem().getStore(fileURI).toString();
				}
			} catch (final CoreException e) {
			}
			if (path == null) {
				path = fileURI.toString();
			}
			final String code = resolveVariables(command, path, encoding);
			connector.submit(Collections.singletonList(code), gotoConsole);
		}
	}
	
	private static String resolveVariables(final String command, final String path, final String encoding)
			throws CoreException {
		final List<IDynamicVariable> variables = new ArrayList<>();
		variables.add(new DynamicVariable(FILE_NAME_VARIABLE) {
			@Override
			public String getValue(final String argument) throws CoreException {
				return RUtil.escapeCompletely(path);
			}
		});
		variables.add(new DynamicVariable(FILE_ENCODING_VARIABLE) {
			@Override
			public String getValue(final String argument) throws CoreException {
				return encoding != null ? RUtil.escapeCompletely(encoding) : "unknown";
			}
		});
		variables.add(new DynamicVariable(ECHO_ENABLED_VARIABLE) {
			@Override
			public String getValue(final String argument) throws CoreException {
				final Boolean echo = PreferenceUtils.getInstancePrefs().getPreferenceValue(
						RCodeLaunching.ECHO_ENABLED_PREF);
				return (echo != null && echo.booleanValue()) ?
						"TRUE" : "FALSE"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		});
		final VariableText text = new VariableText(command, variables, true);
		text.performFinalStringSubstitution(new LocationProcessor() {
			@Override
			public String process(final String path) throws CoreException {
				return RUtil.escapeCompletely(path);
			}
		});
		return text.getText();
	}
	
	private static boolean saveBeforeLaunch(final IProject[] projects) throws CoreException {
		IStatusHandler prompter = null;
		prompter = DebugPlugin.getDefault().getStatusHandler(STATUS_PROMPTER);
		if (prompter != null) {
			return ((Boolean) prompter.handleStatus(STATUS_SAVE,
					new Object[] { null, projects } )).booleanValue();
		}
		return true;
	}
	
	public static boolean runRCodeDirect(final List<String> lines, final boolean gotoConsole,
			final IProgressMonitor monitor) throws CoreException {
		if (monitor != null) {
			monitor.subTask(RLaunchingMessages.RCodeLaunch_SubmitCode_task);
		}
		final IRCodeSubmitConnector connector = RCodeLaunchRegistry.getDefault().getConnector();
		
		return connector.submit(lines, gotoConsole);
	}
	
	public static boolean runRCodeDirect(final List<SourceRegion> codeRegions,
			final boolean gotoConsole) throws CoreException {
		final IRCodeSubmitConnector connector = RCodeLaunchRegistry.getDefault().getConnector();
		if (connector instanceof RControllerCodeLaunchConnector) {
			return ((RControllerCodeLaunchConnector) connector).submit(
					new RControllerCodeLaunchConnector.CommandsCreator() {
				@Override
				public Status submitTo(final ToolController controller) {
					final ToolRunnable[] runnables = new ToolRunnable[codeRegions.size()];
					final List<String> lines = new ArrayList<>();
					for (int i = 0; i < runnables.length; i++) {
						final SourceRegion region = codeRegions.get(i);
						lines.clear();
						TextUtil.addLines(region.fCode, lines);
						runnables[i] = new SubmitEntireCommandRunnable(
								lines.toArray(new String[lines.size()]), region);
					}
					final Status status = controller.getTool().getQueue().add(
							ImCollections.newList(runnables) );
					if (status.getSeverity() != Status.OK) {
						for (int i = 0; i < runnables.length; i++) {
							runnables[i].changed(ToolRunnable.BEING_ABANDONED, null);
						}
					}
					return status;
				}
			}, gotoConsole);
		}
		final List<String> lines = new ArrayList<>(codeRegions.size()*2);
		for (int i = 0; i < codeRegions.size(); i++) {
			TextUtil.addLines(codeRegions.get(i).fCode, lines);
		}
		return runRCodeDirect(lines, gotoConsole, null);
	}
	
	public static final BooleanPref ECHO_ENABLED_PREF = new BooleanPref(
			RRunDebugPreferenceConstants.ROOT_QUALIFIER + "/codelaunch", "echo.enabled" );
	
}
