/*******************************************************************************
 * Copyright (c) 2016 Red Hat Inc. 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/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Mickael Istria (Red Hat Inc.) - initial implementation
 *******************************************************************************/
package org.eclipse.lsp4e;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.RuntimeProcess;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.core.Preferences;
import org.eclipse.lsp4e.server.StreamConnectionProvider;

/**
 * Access and control IO streams from a Launch Configuration to connect
 * them to language server protocol client.
 */
public class LaunchConfigurationStreamProvider implements StreamConnectionProvider  {

	private StreamProxyInputStream inputStream;
	private StreamProxyInputStream errorStream;
	private OutputStream outputStream;
	private ILaunch launch;
	private IProcess process;
	private ILaunchConfiguration launchConfiguration;
	private Set<String> launchModes;

	protected static class StreamProxyInputStream extends InputStream implements IStreamListener {

		private ConcurrentLinkedQueue<Byte> queue = new ConcurrentLinkedQueue<>();
		private IProcess process;

		public StreamProxyInputStream(IProcess process) {
			this.process = process;
		}

		@Override
		public void streamAppended(String text, IStreamMonitor monitor) {
			byte[] bytes = text.getBytes(Charset.defaultCharset());
			List<Byte> bytesAsList = new ArrayList<>(bytes.length);
			for (byte b : bytes) {
				bytesAsList.add(b);
			}
			queue.addAll(bytesAsList);
		}

		@Override
		public int read() throws IOException {
			while (queue.isEmpty()) {
				if (this.process.isTerminated()) {
					return -1;
				}
				try {
					Thread.sleep(5, 0);
				} catch (InterruptedException e) {
					LanguageServerPlugin.logError(e);
					Thread.currentThread().interrupt();
				}
			}
			return queue.poll();
		}

		@Override
		public int available() throws IOException {
			return queue.size();
		}

	}

	public LaunchConfigurationStreamProvider(ILaunchConfiguration launchConfig, Set<String> launchModes) {
		super();
		Assert.isNotNull(launchConfig);
		this.launchConfiguration = launchConfig;
		if (launchModes != null) {
			this.launchModes = launchModes;
		} else {
			this.launchModes = Collections.singleton(ILaunchManager.RUN_MODE);
		}
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof LaunchConfigurationStreamProvider)) {
			return false;
		}
		LaunchConfigurationStreamProvider other = (LaunchConfigurationStreamProvider)obj;
		return this.launchConfiguration.equals(other.launchConfiguration) && this.launchModes.equals(other.launchModes);
	}

	@Override
	public int hashCode() {
		return this.launchConfiguration.hashCode() ^ this.launchModes.hashCode();
	}

	public static ILaunchConfiguration findLaunchConfiguration(String typeId, String name) {
		ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(typeId);
		ILaunchConfiguration res = null;
		try {
			for (ILaunchConfiguration launch : manager.getLaunchConfigurations(type)) {
				if (launch.getName().equals(name)) {
					res = launch;
				}
			}
		} catch (CoreException e) {
			LanguageServerPlugin.logError(e);
		}
		return res;
	}

	@Override
	public void start() throws IOException {
		// Disable status handler to avoid starting launch in an UI Thread which freezes
		// the IDE when Outline is displayed.
		boolean statusHandlerToUpdate = disableStatusHandler();
		try {
			this.launch = this.launchConfiguration.launch(this.launchModes.iterator().next(), new NullProgressMonitor(),
					false);
			long initialTimestamp = System.currentTimeMillis();
			while (this.launch.getProcesses().length == 0 && System.currentTimeMillis() - initialTimestamp < 5000) {
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					LanguageServerPlugin.logError(e);
					Thread.currentThread().interrupt();
				}
			}
			if (this.launch.getProcesses().length > 0) {
				this.process = this.launch.getProcesses()[0];
				this.inputStream = new StreamProxyInputStream(process);
				process.getStreamsProxy().getOutputStreamMonitor().addListener(this.inputStream);
				// TODO: Ugly hack, find something better to retrieve stream!
				try {
					Method systemProcessGetter = RuntimeProcess.class.getDeclaredMethod("getSystemProcess"); //$NON-NLS-1$
					systemProcessGetter.setAccessible(true);
					Process systemProcess = (Process) systemProcessGetter.invoke(process);
					this.outputStream = systemProcess.getOutputStream();
				} catch (ReflectiveOperationException ex) {
					LanguageServerPlugin.logError(ex);
				}
				this.errorStream = new StreamProxyInputStream(process);
				process.getStreamsProxy().getErrorStreamMonitor().addListener(this.errorStream);
			}
		} catch (Exception e) {
			LanguageServerPlugin.logError(e);
		}
		finally {
			if (statusHandlerToUpdate) {
				setStatusHandler(true);
			}
		}
	}

	/**
	 * Disable status handler while launch is done.
	 *
	 * @return true if the status handler preferences was <code>enabled</code> and
	 *         <code>false</code> otherwise.
	 */
	private boolean disableStatusHandler() {
		boolean enabled = Platform.getPreferencesService().getBoolean(DebugPlugin.getUniqueIdentifier(),
				IInternalDebugCoreConstants.PREF_ENABLE_STATUS_HANDLERS, false, null);
		if (enabled) {
			setStatusHandler(false);
		}
		return enabled;
	}

	/**
	 * Update the the status handler preferences
	 *
	 * @param enabled
	 *            the status handler preferences
	 */
	private void setStatusHandler(boolean enabled) {
		Preferences.setBoolean(DebugPlugin.getUniqueIdentifier(),
				IInternalDebugCoreConstants.PREF_ENABLE_STATUS_HANDLERS, enabled, null);
	}

	@Override
	public InputStream getInputStream() {
		return this.inputStream;
	}

	@Override
	public OutputStream getOutputStream() {
		return this.outputStream;
	}

	@Override
	public InputStream getErrorStream() {
		return this.errorStream;
	}

	@Override
	public void stop() {
		if (this.launch == null) {
			return;
		}
		try {
			this.launch.terminate();
			for (IProcess p : this.launch.getProcesses()) {
				p.terminate();
			}
		} catch (DebugException e1) {
			LanguageServerPlugin.logError(e1);
		}
		this.launch = null;
		this.process = null;
		try {
			if (this.inputStream != null) {
				this.inputStream.close();
			}
		} catch (IOException e) {
			LanguageServerPlugin.logError(e);
		}
		try {
			if (this.errorStream != null) {
				this.errorStream.close();
			}
		} catch (IOException e) {
			LanguageServerPlugin.logError(e);
		}
		this.inputStream = null;
		this.outputStream = null;
		this.errorStream = null;
	}

}
