/*=============================================================================#
 # Copyright (c) 2011, 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.nico.core.runtime;

import java.util.Map;

import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IFlushableStreamMonitor;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.debug.core.model.RuntimeProcess;


/**
 * Runtime process supporting logging of the process output without attaching a console
 */
public class LogRuntimeProcess extends RuntimeProcess {
	
	
	private boolean fLogOnly;
	
	private RuntimeProcessOutput fLog;
	
	
	public LogRuntimeProcess(final ILaunch launch, final Process process, final String name,
			final Map<String, String> attributes) {
		super(launch, process, name, attributes);
	}
	
	
	@Override
	protected IStreamsProxy createStreamsProxy() {
		fLogOnly = ToolRunner.captureLogOnly(getLaunch().getLaunchConfiguration());
		final IStreamsProxy proxy = super.createStreamsProxy();
		if (fLogOnly) {
			fLog = new RuntimeProcessOutput(proxy, fLogOnly);
		}
		return proxy;
	}
	
	@Override
	public IStreamsProxy getStreamsProxy() {
		if (!fLogOnly) {
			return super.getStreamsProxy();
		}
		return null;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(final Class<T> adapterType) {
		if (adapterType == ILogOutput.class) {
			return (T) fLog;
		}
		return super.getAdapter(adapterType);
	}
	
}


class RuntimeProcessOutput implements ILogOutput {
	
	
	private final class StreamListener implements IStreamListener {
		
		private final IStreamMonitor fStreamMonitor;
		
		private boolean fFlushed;
		
		private StreamListener(final IStreamMonitor streamMonitor) {
			fStreamMonitor = streamMonitor;
			fStreamMonitor.addListener(this);
		}
		
		@Override
		public void streamAppended(final String text, final IStreamMonitor monitor) {
			if (!fFlushed) {
				String contents = null;
				synchronized (fStreamMonitor) {
					fFlushed = true;
					contents = fStreamMonitor.getContents();
					if (fFlush && fStreamMonitor instanceof IFlushableStreamMonitor) {
						final IFlushableStreamMonitor m = (IFlushableStreamMonitor) fStreamMonitor;
						m.flushContents();
						m.setBuffered(false);
					}
				}
				append(contents);
			}
			else {
				append(text);
			}
		}
		
		public void init() {
			streamAppended(null, fStreamMonitor);
		}
		
		public void dispose() {
			fStreamMonitor.removeListener(this);
		}
		
	}
	
	
	private final StringBuilder fStringBuilder = new StringBuilder(0x1000);
	
	private StreamListener fOutputStreamListener;
	private StreamListener fErrorStreamListener;
	
	private final boolean fFlush;
	private final int fHighWater;
	private final int fLowWater;
	
	
	public RuntimeProcessOutput(final IStreamsProxy proxy, final boolean flush) {
		fFlush = flush;
		fHighWater = 0x10000;
		fLowWater = fHighWater - 0x1000;
		
		fOutputStreamListener = new StreamListener(proxy.getOutputStreamMonitor());
		fErrorStreamListener = new StreamListener(proxy.getErrorStreamMonitor());
		fOutputStreamListener.init();
		fErrorStreamListener.init();
	}
	
	
	private synchronized void append(final String text) {
		if (text == null) {
			return;
		}
		if (fStringBuilder.length() + text.length() > fHighWater) {
			int idx = fStringBuilder.length() + text.length() - fLowWater;
			boolean found = false;
			while (idx < fStringBuilder.length()) {
				final char c = fStringBuilder.charAt(idx++);
				if (c == '\n' || c == '\r') {
					found = true;
				}
				else if (found) {
					idx--;
					break;
				}
			}
			fStringBuilder.delete(0, idx);
		}
		fStringBuilder.append(text);
	}
	
	public synchronized void dispose() {
		if (fOutputStreamListener != null) {
			fOutputStreamListener.dispose();
			fOutputStreamListener = null;
		}
		if (fErrorStreamListener != null) {
			fErrorStreamListener.dispose();
			fErrorStreamListener = null;
		}
	}
	
	@Override
	public synchronized String getOutput() {
		return fStringBuilder.toString();
	}
	
}
