/*=============================================================================#
 # Copyright (c) 2017, 2019 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.apps.ui.launching;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Objects;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.variables.IStringVariable;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.statushandlers.StatusManager;

import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.InfoStatus;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.ts.core.RunnableStatus;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.jcommons.ts.core.ToolRunnable;

import org.eclipse.statet.ecommons.runtime.core.util.StatusUtils;
import org.eclipse.statet.ecommons.ui.mpbv.BrowserSession;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.variables.core.StaticVariable;
import org.eclipse.statet.ecommons.variables.core.VariableText2;
import org.eclipse.statet.ecommons.variables.core.VariableUtils;

import org.eclipse.statet.internal.r.apps.ui.Messages;
import org.eclipse.statet.internal.r.apps.ui.RAppUIPlugin;
import org.eclipse.statet.internal.r.apps.ui.variables.AppVarView;
import org.eclipse.statet.internal.r.apps.ui.viewer.AppBrowserSession;
import org.eclipse.statet.internal.r.apps.ui.viewer.AppBrowserView;
import org.eclipse.statet.nico.core.runtime.Queue;
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.apps.ui.AppRegistry;
import org.eclipse.statet.r.apps.ui.RApp;
import org.eclipse.statet.r.apps.ui.VariablesData;
import org.eclipse.statet.r.console.core.RConsoleTool;
import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.console.core.RWorkspace;
import org.eclipse.statet.r.console.core.util.RCodeVariableText;
import org.eclipse.statet.r.core.tool.AbstractStatetRRunnable;
import org.eclipse.statet.r.core.tool.IRConsoleService;
import org.eclipse.statet.r.nico.impl.RjsUtil;
import org.eclipse.statet.rj.ts.core.AbstractRToolRunnable;
import org.eclipse.statet.rj.ts.core.RToolService;


@NonNullByDefault
public class AppRunner extends AbstractStatetRRunnable implements RApp {
	
	
	public static final String RUN_TASK_ID= "org.eclipse.statet.r.apps/RunApp"; //$NON-NLS-1$
	public static final String STOP_TASK_ID= "org.eclipse.statet.r.apps/StopApp"; //$NON-NLS-1$
	
	private static final String LOCALHOST= "127.0.0.1"; //$NON-NLS-1$
	
	private static final Status NOT_RUNNING_DATA_STATUS= new InfoStatus(RAppUIPlugin.BUNDLE_ID,
			"The app is not running." );
	private static final Status NOT_LOADED_DATA_STATUS= new InfoStatus(RAppUIPlugin.BUNDLE_ID,
			"Variabes are not yet available." );
	
	
	public static RProcess fetchRProcess(final IWorkbenchPage page) throws CoreException {
		final Tool tool= NicoUI.getToolRegistry().getActiveToolSession(page).getTool();
		NicoUITools.accessTool(RConsoleTool.TYPE, tool);
		return (RProcess)tool;
	}
	
	
	private class AppSession {
		
		private final RProcess rProcess;
		
		private Queue.Section queueSection;
		
		private String host;
		private String remoteHost;
		private int remotePort;
		private @Nullable Session sshSession;
		private int sshLocalPort= -1;
		
		private @Nullable URL localUrl;
		private @Nullable URL idUrl;
		
		private boolean isRunning;
		
		private long startedTimestamp;
		
		
		public AppSession(final RProcess tool) {
			this.rProcess= tool;
		}
		
		
		public RProcess getTool() {
			return this.rProcess;
		}
		
		public boolean isRunning() {
			return this.isRunning;
		}
		
		public void init(final ProgressMonitor m) throws StatusException {
			{	this.queueSection= this.rProcess.getController().getCurrentQueueSection();
			}
			{	final String host= AppRunner.this.config.getAppHost();
				if (host.isEmpty()) {
					final RWorkspace workspaceData= this.rProcess.getWorkspaceData();
					if (workspaceData.isRemote()) {
						this.host= workspaceData.getRemoteAddress();
						final Map<String, Object> connectionInfo= this.rProcess.getConnectionInfo();
						if (connectionInfo != null && Objects.equals(connectionInfo.get("protocol"), "ssh")) {
							this.remoteHost= LOCALHOST;
							this.sshSession= RjsUtil.getSession(connectionInfo, m);
						}
					}
					else {
						this.host= LOCALHOST;
					}
				}
				else {
					this.host= host;
				}
				if (this.remoteHost == null) {
					this.remoteHost= this.host;
				}
				this.remotePort= AppRunner.this.config.getAppPort();
			}
		}
		
		public String getStartCode() throws StatusException {
			{	final String code= AppRunner.this.config.getStartCode();
				
				final Map<String, IStringVariable> variables= AppRunner.this.config.getVariables();
				VariableUtils.add(variables, new StaticVariable(
						AppControlConfigs.APP_HOST_VAR,
						this.remoteHost ));
				VariableUtils.add(variables, new StaticVariable(
						AppControlConfigs.APP_PORT_VAR,
						(this.remotePort > 0) ? Integer.toString(this.remotePort) : "NULL" )); //$NON-NLS-1$
				
				final VariableText2 variableText= new RCodeVariableText(
						this.rProcess.getWorkspaceData(), variables );
				try {
					return variableText.performStringSubstitution(code, null);
				}
				catch (final CoreException e) {
					throw new StatusException(new ErrorStatus(RAppUIPlugin.BUNDLE_ID,
							NLS.bind(Messages.Operation_StartApp_RCode_error_SpecInvalid_message,
							 e.getMessage() )));
				}
			}
		}
		
		public boolean onStarted(final String url) {
			try {
				final URL rUrl;
				try {
					rUrl= new URL(url);
				}
				catch (final MalformedURLException e) {
					throw new StatusException(new ErrorStatus(RAppUIPlugin.BUNDLE_ID,
							NLS.bind("Invalid URL of the R app from R= ''{0}''.", url),
							e ));
				}
				
				if (this.sshSession != null) {
					try {
						this.sshLocalPort= this.sshSession.setPortForwardingL(0, LOCALHOST,
								(rUrl.getPort() != -1) ? rUrl.getPort() : 80 );
						this.localUrl= new URL(rUrl.getProtocol(), LOCALHOST, this.sshLocalPort,
								rUrl.getFile() );
						this.idUrl= new URL(rUrl.getProtocol(), this.host, rUrl.getPort(),
								rUrl.getFile() );
					}
					catch (final JSchException e) {
						throw new StatusException(new ErrorStatus(RAppUIPlugin.BUNDLE_ID,
								"Failed create SSH tunnel for http connection of the R app.",
								e ));
					}
				}
				else if (!this.host.equals(rUrl.getHost())) {
					this.localUrl= new URL(rUrl.getProtocol(), this.host, rUrl.getPort(),
							rUrl.getFile() );
					this.idUrl= this.localUrl;
				}
				else {
					this.localUrl= rUrl;
					this.idUrl= this.localUrl;
				}
			}
			catch (final Exception e) {
				onError(IStatus.ERROR, "An error occurred when preparing to show the R app.", e,
						(AppRunner.this.config.getViewerId() != null) ?
								StatusManager.LOG | StatusManager.SHOW :
								StatusManager.LOG );
				return false;
			}
			
			synchronized (AppRunner.this) {
				this.isRunning= true;
				this.startedTimestamp= System.nanoTime();
				return true;
			}
		}
		
		public URL getLocalUrl() {
			return this.localUrl;
		}
		
		public URL getIdUrl() {
			return this.idUrl;
		}
		
		public void onAppStop() {
			synchronized (AppRunner.this) {
				this.isRunning= false;
			}
			
			this.queueSection= null;
			
			if (this.sshSession != null && this.sshLocalPort > 0) {
				try {
					this.sshSession.delPortForwardingL(this.sshLocalPort);
				}
				catch (final JSchException e) {
					RAppUIPlugin.logError("Failed delete SSH tunnel for http connection of the R app.",
							e );
				}
				this.sshLocalPort= -1;
			}
		}
		
	}
	
	public class StopRunnable extends AbstractRToolRunnable {
		
		
		public StopRunnable() {
			super(STOP_TASK_ID, "Stop R App"); //$NON-NLS-1$
		}
		
		
		@Override
		public boolean changed(final int event, final Tool tool) {
			switch (event) {
			case MOVING_FROM:
				return false;
			default:
				return true;
			}
		}
		
		@Override
		protected void run(final RToolService r,
				final ProgressMonitor m) throws StatusException {
			AppSession session;
			synchronized (AppRunner.this) {
				session= AppRunner.this.session;
				if (session == null || !session.isRunning()) {
					return;
				}
			}
			
			final String code= AppRunner.this.config.getStopCode();
			r.evalVoid(code, m);
		}
		
	}
	
	
	private final AppControlLaunchConfig config;
	
	private final CopyOnWriteIdentityListSet<Listener> listeners= new CopyOnWriteIdentityListSet<>();
	
	private @Nullable AppSession session;
	
	private @Nullable RProcess tool;
	private @Nullable IWorkbenchPage workbenchPage;
	
	private @Nullable DataLoader variablesLoader;
	private @Nullable volatile VariablesData variablesData;
	
	
	public AppRunner(final AppControlLaunchConfig config) {
		super(RUN_TASK_ID, NLS.bind("Run R App ''{0}''",
				config.getAppFolder().getFullPath().toString() ));
		
		this.config= config;
		initVars();
	}
	
	
	@Override
	public IResource getResource() {
		return this.config.getAppFolder();
	}
	
	
	@Override
	protected void run(final IRConsoleService r,
			final ProgressMonitor m) throws StatusException {
		final AppSession session;
		AppRCommandHandler listener= null;
		try {
			synchronized (this) {
				this.tool= (RProcess) r.getTool();
				session= new AppSession(this.tool);
				this.session= session;
			}
			
			session.init(m);
			
			listener= AppRCommandHandler.connect(this, r, m);
			
			r.briefAboutToChange();
			
			r.submitToConsole(session.getStartCode(), m);
		}
		finally {
			r.briefChanged(IRConsoleService.AUTO_CHANGE);
			
			onAppStopped(null);
			
			if (listener != null) {
				listener.disconnect(this);
			}
		}
	}
	
	protected void onAppStarted(final String url, final String typeId) {
		final AppSession session;
		synchronized (this) {
			session= this.session;
			if (session == null) {
				return;
			}
		}
		
		final boolean isRunning= session.onStarted(url);
		updateVarsOnStarted();
		
		if (isRunning) {
			AppRegistry.getInstance().onAppStarted(session.getIdUrl(), this);
			
			if (this.config.getViewerId() != null) {
				showViewer(session, this.config.getViewerId());
			}
			if (this.config.getVariablesViewAction() != 0 && this.variablesData != null) {
				showVariablesView(session, this.config.getVariablesViewAction());
			}
			refreshVariables();
		}
	}
	
	protected void onAppStopped(final @Nullable String url) {
		final AppSession session;
		synchronized (this) {
			session= this.session;
			if (session == null) {
				return;
			}
			
			this.session= null;
		}
		
		session.onAppStop();
		
		if (session.getIdUrl() != null) {
			AppRegistry.getInstance().onAppStopped(session.getIdUrl(), this);
		}
		
		updateVarsOnStopped();
	}
	
	
	@Override
	public @Nullable RProcess getTool() {
		return this.tool;
	}
	
	protected IWorkbenchPage getWorkbenchPage() {
		IWorkbenchPage page= this.workbenchPage;
		if (page == null) {
			page= this.config.getWorkbenchPage();
		}
		if (page != null && page.getWorkbenchWindow().getActivePage() == page) {
			return page;
		}
		page= UIAccess.getActiveWorkbenchPage(true);
		this.workbenchPage= page;
		return page;
	}
	
	@Override
	public boolean isRunning() {
		final AppSession session;
		synchronized (this) {
			session= this.session;
			
			return (session != null && session.isRunning());
		}
	}
	
	long getStartedTimestamp() {
		final AppSession session;
		synchronized (this) {
			session= this.session;
			
			return (session != null && session.isRunning()) ? session.startedTimestamp : Long.MIN_VALUE;
		}
	}
	
	@Override
	public void startApp(final IWorkbenchPage page) throws CoreException {
		final RProcess tool= fetchRProcess(page);
		
		final Status status= tryStart(tool);
		if (status.getSeverity() < Status.ERROR) {
			return;
		}
		
		throw new CoreException(StatusUtils.convert(status));
	}
	
	@Override
	public boolean canRestartApp() { // (!isRunning() || canStopApp())
		final AppSession session;
		synchronized (this) {
			session= this.session;
			if (session == null || !session.isRunning()) {
				return true;
			}
		}
		
		return (this.config.getStopCode() != null);
	}
	
	@Override
	public void restartApp(final IWorkbenchPage page) throws CoreException {
		final AppSession session;
		RProcess tool;
		Queue.Section queueSection;
		synchronized (this) {
			tool= this.tool;
			session= this.session;
			
			queueSection= (session != null && session.isRunning()) ? session.queueSection : null;
		}
		
		final AppRunner runner= new AppRunner(this.config);
		runner.workbenchPage= this.workbenchPage;
		
		Status status= null;
		if (tool != null) {
			if (queueSection != null && queueSection != tool.getQueue().getTopLevelSection()) {
				final Status status0= runner.tryRestart(tool, queueSection);
				if (status0.getSeverity() < Status.ERROR) {
					return;
				}
			}
			{	final Status status0= runner.tryRestart(tool, tool.getQueue().getTopLevelSection());
				if (status0.getSeverity() < Status.ERROR) {
					return;
				}
				if (status == null) {
					status= status0;
				}
			}
		}
		
		{	tool= fetchRProcess(page);
			final Status status0= runner.tryRestart(tool, tool.getQueue().getTopLevelSection());
			if (status0.getSeverity() < Status.ERROR) {
				return;
			}
			if (status == null) {
				status= status0;
			}
		}
		
		throw new CoreException(StatusUtils.convert(status));
	}
	
	private Status tryStart(final RProcess tool) {
		final Queue queue= tool.getQueue();
		final Status status= queue.add(this);
		
		if (status.getSeverity() < Status.ERROR) {
			stopBlocking(tool, this.config.getStopBlocking());
		}
		
		return status;
	}
	
	private Status tryRestart(final RProcess tool, final Queue.Section queueSection) {
		final Queue queue= tool.getQueue();
		final Status status= queue.add(this, queueSection, Queue.IF_ABSENT);
		
		if (status.getSeverity() < Status.ERROR) {
			final AppRunner runner= (AppRunner) ((RunnableStatus) status).getRunnable();
			
			runner.stopBlocking(tool, this.config.getStopBlocking() | 2);
		}
		
		return status;
	}
	
	private void stopBlocking(final RProcess tool, final int mode) {
		if (mode == 0) {
			return;
		}
		final ToolController controller= tool.getController();
		if (controller != null) {
			final ToolRunnable currentRunnable= controller.getCurrentRunnable();
			if (currentRunnable != this && currentRunnable instanceof AppRunner) {
				final AppRunner runner= (AppRunner) currentRunnable;
				if ((mode & 1) != 0
						|| ((mode & 2) != 0 && runner.config == this.config) ) {
					runner.stopApp();
				}
			}
		}
	}
	
	@Override
	public boolean canStopApp() {
		final AppSession session;
		synchronized (this) {
			session= this.session;
			if (session == null || !session.isRunning()) {
				return false;
			}
		}
		
		return (this.config.getStopCode() != null);
	}
	
	@Override
	public void stopApp() {
		final AppSession session;
		synchronized (this) {
			session= this.session;
			if (session == null) {
				return;
			}
		}
		
		if (this.config.getStopCode() != null) {
			session.getTool().getQueue().addHot(new StopRunnable());
		}
	}
	
	
	private void showViewer(final AppSession session, final String viewerId) {
		if (session.getLocalUrl() == null) {
			onError(IStatus.ERROR, "Cannot open viewer to show the R app: URL is missing.", null,
					StatusManager.SHOW );
			return;
		}
		
		UIAccess.getDisplay().asyncExec(() -> {
			synchronized (AppRunner.this) {
				if (session != this.session || !session.isRunning()) {
					return;
				}
			}
			try {
				switch (viewerId) {
				case AppControlConfigs.WORKBENCH_EXTERNAL_BROWSER_ID:
					openExternalBrowser(session);
					return;
				case AppControlConfigs.WORKBENCH_VIEW_BROWSER_ID:
					openViewBrowser(getWorkbenchPage(), session);
					return;
				default:
					throw new UnsupportedOperationException("viewerId= " + viewerId); //$NON-NLS-1$
				}
			}
			catch (final Exception e) {
				onError(IStatus.ERROR, Messages.Operation_Viewer_error_Run_message, e,
						StatusManager.LOG | StatusManager.SHOW );
			}
		});
	}
	
	private void openExternalBrowser(final AppSession session) throws PartInitException {
		final IWorkbenchBrowserSupport browserSupport= PlatformUI.getWorkbench().getBrowserSupport();
		final IWebBrowser webBrowser= browserSupport.getExternalBrowser();
		webBrowser.openURL(session.getLocalUrl());
	}
	
	private AppBrowserView getView(final IWorkbenchPage page) throws PartInitException {
		return (AppBrowserView) page.showView(AppBrowserView.VIEW_ID, null,
				IWorkbenchPage.VIEW_VISIBLE );
	}
	
	private void openViewBrowser(final IWorkbenchPage page, final AppSession session) throws PartInitException {
		final AppBrowserView view= getView(page);
		AppBrowserSession viewSession= (AppBrowserSession) BrowserSession.findSessionById(
				view.getSessions(), session.getIdUrl() );
		if (viewSession == null) {
			viewSession= new AppBrowserSession(session.getIdUrl());
		}
		view.openUrl(session.getLocalUrl().toExternalForm(), viewSession);
	}
	
	
	private void showVariablesView(final AppSession session, final int viewActionMode) {
		UIAccess.getDisplay().asyncExec(() -> {
			synchronized (AppRunner.this) {
				if (session != this.session || !session.isRunning()) {
					return;
				}
			}
			try {
				final IWorkbenchPage page= getWorkbenchPage();
				final IViewReference viewRef= page.findViewReference(AppVarView.VIEW_ID);
				if (viewRef != null) {
					if (viewRef.isFastView()) {
						return;
					}
					final IViewPart view= viewRef.getView(false);
					if (view != null && page.isPartVisible(view)) {
						return;
					}
				}
				final AppVarView view= (AppVarView) page.showView(AppVarView.VIEW_ID, null,
						viewActionMode );
				view.setShownByLauncher(this);
			}
			catch (final PartInitException e) {
				onError(IStatus.ERROR, Messages.Operation_Variables_error_Run_message, e);
			}
		});
	}
	
	
	@Override
	public void addListener(final Listener listener) {
		boolean refresh;
		synchronized (this.listeners) {
			refresh= (this.listeners.isEmpty() && this.variablesLoader == null);
			
			this.listeners.add(listener);
		}
		if (refresh) {
			refreshVariables();
		}
	}
	
	@Override
	public void removeListener(final Listener listener) {
		this.listeners.remove(listener);
	}
	
	@Override
	public @Nullable VariablesData getVariables() {
		return this.variablesData;
	}
	
	private void initVars() {
		final String code= this.config.getVariablesCode();
		if (code == null) {
			return;
		}
		this.variablesData= new VariablesData(code, NOT_RUNNING_DATA_STATUS);
	}
	
	private void updateVarsOnStarted() {
		final VariablesData data= this.variablesData;
		if (data == null || data.getStatus() != NOT_RUNNING_DATA_STATUS) {
			return;
		}
		setData(new VariablesData(data.getExpression(), NOT_LOADED_DATA_STATUS));
	}
	
	@Override
	public void refreshVariables() {
		final VariablesData data= this.variablesData;
		if (data == null) {
			return;
		}
		DataLoader loader;
		synchronized (this.listeners) {
			loader= this.variablesLoader;
			if (loader == null) {
				if (this.listeners.isEmpty() || !isRunning()) {
					return;
				}
				loader= new DataLoader(this, data.getExpression());
				this.variablesLoader= loader;
			}
		}
		loader.schedule();
	}
	
	private void updateVarsOnStopped() {
		final VariablesData data= this.variablesData;
		if (data == null) {
			return;
		}
		DataLoader loader;
		synchronized (this.listeners) {
			loader= this.variablesLoader;
			this.variablesLoader= null;
		}
		if (loader != null) {
			loader.stop();
		}
		setData(new VariablesData(data.getExpression(), NOT_RUNNING_DATA_STATUS));
	}
	
	void setData(final VariablesData variables) {
		this.variablesData= variables;
		
		final AppEvent event= new AppEvent(this);
		for (final Listener listener : this.listeners) {
			listener.onVariablesChanged(event);
		}
	}
	
	private void onError(final int severity, final String message, final @Nullable Throwable e,
			final int style) {
		StatusManager.getManager().handle(new org.eclipse.core.runtime.Status(
						severity, RAppUIPlugin.BUNDLE_ID, message, e ),
				style );
	}
	
	private void onError(final int severity, final String message, final @Nullable Throwable e) {
		onError(severity, message, e, StatusManager.LOG);
	}
	
	
	@Override
	public int hashCode() {
		return this.config.hashCode();
	}
	
	@Override
	public boolean equals(final @Nullable Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof AppRunner) {
			return (this.config == ((AppRunner) obj).config);
		}
		return false;
	}
	
}
