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

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.variables.IDynamicVariable;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.ts.core.SystemRunnable;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.jcommons.ts.core.ToolService;

import org.eclipse.statet.ecommons.io.FileUtil;
import org.eclipse.statet.ecommons.net.resourcemapping.core.ResourceMappingUtils;
import org.eclipse.statet.ecommons.runtime.core.util.PathUtils;
import org.eclipse.statet.ecommons.variables.core.DateVariable;
import org.eclipse.statet.ecommons.variables.core.DynamicVariable;
import org.eclipse.statet.ecommons.variables.core.TimeVariable;

import org.eclipse.statet.internal.nico.core.NicoCorePlugin;
import org.eclipse.statet.nico.core.NicoCore;
import org.eclipse.statet.nico.core.NicoVariables;
import org.eclipse.statet.nico.core.runtime.ToolController.IToolStatusListener;


/**
 * It belongs to a ToolProcess and has the same life cycle.
 */
public class ToolWorkspace {
	
	
	public static interface Listener {
		
		public void propertyChanged(ToolWorkspace workspace, Map<String, Object> properties);
		
	}
	
	
	private class ControllerListener implements IToolStatusListener {
		
		@Override
		public void controllerStatusChanged(final ToolStatus oldStatus, final ToolStatus newStatus, final List<DebugEvent> eventCollection) {
			if (newStatus == ToolStatus.TERMINATED) {
				dispose();
			}
			
			// by definition in tool lifecycle thread
			if (!newStatus.isRunning()) {
				if (ToolWorkspace.this.currentPrompt == null || ToolWorkspace.this.currentPrompt == ToolWorkspace.this.publishedPrompt) {
					return;
				}
				ToolWorkspace.this.publishedPrompt= ToolWorkspace.this.currentPrompt;
				firePrompt(ToolWorkspace.this.currentPrompt, eventCollection);
				return;
			}
			else {
				ToolWorkspace.this.publishedPrompt= ToolWorkspace.this.defaultPrompt;
				firePrompt(ToolWorkspace.this.defaultPrompt, eventCollection);
			}
		}
		
	}
	
	private class AutoUpdater implements SystemRunnable {
		
		
		@Override
		public String getTypeId() {
			return "common/workspace/update.auto";
		}
		
		@Override
		public String getLabel() {
			return "Auto Update";
		}
		
		@Override
		public boolean canRunIn(final Tool tool) {
			return (tool == ToolWorkspace.this.process);
		}
		
		@Override
		public boolean changed(final int event, final Tool tool) {
			switch (event) {
			case REMOVING_FROM:
			case MOVING_FROM:
				return false;
			}
			return true;
		}
		
		@Override
		public void run(final ToolService service, final ProgressMonitor m) throws StatusException {
			ToolWorkspace.this.isRefreshing= true;
			try {
				autoRefreshFromTool((ConsoleService) service, m);
			}
			finally {
				ToolWorkspace.this.isRefreshing= false;
			}
			firePropertiesChanged();
		}
		
	}
	
	
	public static final int DETAIL_PROMPT= 1;
	public static final int DETAIL_LINE_SEPARTOR= 2;
	
	
	private final ToolProcess process;
	
	private volatile String lineSeparator;
	private volatile char fileSeparator;
	
	private volatile Prompt currentPrompt;
	private volatile Prompt defaultPrompt;
	private Prompt publishedPrompt;
	
	private IFileStore workspaceDir;
	
	private final String remoteHost;
	private IPath remoteWorkspaceDirPath;
	
	private final Map<String, Object> properties= new HashMap<>();
	private final CopyOnWriteIdentityListSet<Listener> propertyListener= new CopyOnWriteIdentityListSet<>();
	
	private boolean autoRefreshEnabled= true;
	
	private boolean isRefreshing;
	
	private final ImList<IDynamicVariable> stringVariables;
	
	private int changeFlags;
	
	
	public ToolWorkspace(final ToolController controller,
			Prompt prompt, final String lineSeparator, final char fileSeparator,
			final String remoteHost) {
		this.process= controller.getTool();
		if (prompt == null) {
			prompt= Prompt.DEFAULT;
		}
		this.publishedPrompt= this.currentPrompt= this.defaultPrompt= prompt;
		this.remoteHost= remoteHost;
		controlSetLineSeparator(lineSeparator);
		controlSetFileSeparator(fileSeparator);
		
		controller.addToolStatusListener(new ControllerListener());
		controller.getQueue().addOnIdle(new AutoUpdater(), 5000);
		
		this.stringVariables= ImCollections.<IDynamicVariable>newList(
				new DateVariable(NicoVariables.SESSION_STARTUP_DATE_VARIABLE) {
					@Override
					protected long getTimestamp() {
						return ToolWorkspace.this.process.getStartupTimestamp();
					}
				},
				new TimeVariable(NicoVariables.SESSION_STARTUP_TIME_VARIABLE) {
					@Override
					protected long getTimestamp() {
						return ToolWorkspace.this.process.getStartupTimestamp();
					}
				},
				new DateVariable(NicoVariables.SESSION_CONNECTION_DATE_VARIABLE) {
					@Override
					protected long getTimestamp() {
						return ToolWorkspace.this.process.getConnectionTimestamp();
					}
				},
				new TimeVariable(NicoVariables.SESSION_CONNECTION_TIME_VARIABLE) {
					@Override
					protected long getTimestamp() {
						return ToolWorkspace.this.process.getStartupTimestamp();
					}
				},
				new DynamicVariable.LocationVariable(NicoVariables.SESSION_STARTUP_WD_VARIABLE) {
					@Override
					public String getValue(final String argument) throws CoreException {
						return ToolWorkspace.this.process.getStartupWD();
					}
				} );
	}
	
	
	public ToolProcess getProcess() {
		return this.process;
	}
	
	public boolean isWindows() {
		return (getFileSeparator() == '\\');
	}
	
	
	public void setAutoRefresh(final boolean enable) {
		synchronized (this.process.getQueue()) {
			if (this.autoRefreshEnabled != enable) {
				this.autoRefreshEnabled= enable;
				final ToolStatus status= this.process.getToolStatus();
				if (status != ToolStatus.TERMINATED) {
					if (enable && status.isWaiting()) {
						this.process.getQueue().internal_resetOnIdle();
						this.process.getQueue().notifyAll();
					}
					addPropertyChanged("AutoRefresh.enabled", enable);
					firePropertiesChanged();
				}
			}
		}
	}
	
	public boolean isAutoRefreshEnabled() {
		return this.autoRefreshEnabled;
	}
	
	
	protected void autoRefreshFromTool(final ConsoleService service,
			final ProgressMonitor m) throws StatusException {
		if (this.autoRefreshEnabled) {
			refreshFromTool(0, service, m);
		}
	}
	
	protected void refreshFromTool(final int options, final ConsoleService service,
			final ProgressMonitor m) throws StatusException {
	}
	
	
	protected final int getChangeFlags() {
		return this.changeFlags;
	}
	
	protected void controlBriefChanged(final Object obj, final int flags) {
		this.changeFlags|= flags;
	}
	
	protected void clearBriefedChanges() {
		this.changeFlags= 0;
	}
	
	public final String getLineSeparator() {
		return this.lineSeparator;
	}
	
	public final char getFileSeparator() {
		return this.fileSeparator;
	}
	
	
	public final Prompt getPrompt() {
		return this.publishedPrompt;
	}
	
	protected final Prompt getCurrentPrompt() {
		return this.currentPrompt;
	}
	
	public final Prompt getDefaultPrompt() {
		return this.defaultPrompt;
	}
	
	public final IFileStore getWorkspaceDir() {
		return this.workspaceDir;
	}
	
	public String getEncoding() {
		return "UTF-8"; //$NON-NLS-1$
	}
	
	
	public final boolean isRemote() {
		return (this.remoteHost != null);
	}
	
	public String getRemoteAddress() {
		return this.remoteHost;
	}
	
	public IPath getRemoteWorkspaceDirPath() {
		return this.remoteWorkspaceDirPath;
	}
	
	public IPath createToolPath(String toolPath) {
		if (toolPath == null) {
			return null;
		}
		if (isWindows() && File.separatorChar == '/') {
			toolPath= toolPath.replace('\\', '/');
		}
		return PathUtils.check(new Path(toolPath));
	}
	
	public IFileStore toFileStore(final IPath toolPath) throws CoreException {
		if (this.remoteHost != null) {
			return ResourceMappingUtils.getManager()
					.mapRemoteResourceToFileStore(this.remoteHost, toolPath,
							(this.remoteWorkspaceDirPath != null) ? this.remoteWorkspaceDirPath : null );
		}
		return FileUtil.getFileStore(toolPath.toString(), this.workspaceDir);
	}
	
	public IFileStore toFileStore(final String toolPath) throws CoreException {
		if (this.remoteHost != null) {
			return toFileStore(createToolPath(toolPath));
		}
		return FileUtil.getFileStore(toolPath.toString(), this.workspaceDir);
	}
	
	public String toToolPath(final IFileStore fileStore) throws StatusException {
		if (this.remoteHost != null) {
			final IPath path= ResourceMappingUtils.getManager()
					.mapFileStoreToRemoteResource(this.remoteHost, fileStore);
			if (path != null) {
				return path.toString();
			}
			throw new StatusException(new ErrorStatus(NicoCore.BUNDLE_ID,
					"Resolving path for the remote system failed." ));
		}
		return URIUtil.toPath(fileStore.toURI()).toString();
	}
	
	
	final void controlRefresh(final int options, final ConsoleService adapter,
			final ProgressMonitor m) throws StatusException {
		this.isRefreshing= true;
		try {
			refreshFromTool(options, adapter, m);
		}
		finally {
			this.isRefreshing= false;
		}
		firePropertiesChanged();
	}
	
	
	/**
	 * Use only in tool main thread.
	 * @param prompt the new prompt, null doesn't change anything
	 */
	final void controlSetCurrentPrompt(final Prompt prompt, final ToolStatus status) {
		if (prompt == this.currentPrompt || prompt == null) {
			return;
		}
		this.currentPrompt= prompt;
		if (!status.isRunning()) {
			this.publishedPrompt= prompt;
			firePrompt(prompt, null);
		}
	}
	
	/**
	 * Use only in tool main thread.
	 * @param prompt the new prompt, null doesn't change anything
	 */
	final void controlSetDefaultPrompt(final Prompt prompt) {
		if (prompt == this.defaultPrompt || prompt == null) {
			return;
		}
		final Prompt oldDefault= this.defaultPrompt;
		this.defaultPrompt= prompt;
		if (oldDefault == this.currentPrompt) {
			this.currentPrompt= prompt;
		}
		if (oldDefault == this.publishedPrompt) {
			this.publishedPrompt= prompt;
			firePrompt(prompt, null);
		}
	}
	
	/**
	 * Use only in tool main thread.
	 * 
	 * The default separator is System.getProperty("line.separator") for local
	 * workspaces, and '\n' for remote workspaces.
	 * 
	 * @param newSeparator the new line separator, null sets the default separator
	 */
	final void controlSetLineSeparator(final String newSeparator) {
		final String oldSeparator= this.lineSeparator;
		if (newSeparator != null) {
			this.lineSeparator= newSeparator;
		}
		else {
			this.lineSeparator= (this.remoteHost == null) ? System.getProperty("line.separator") : "\n"; //$NON-NLS-1$
		}
//		if (!fLineSeparator.equals(oldSeparator)) {
//			DebugEvent event= new DebugEvent(ToolWorkspace.this, DebugEvent.CHANGE, DETAIL_LINE_SEPARTOR);
//			event.setData(fLineSeparator);
//			fireEvent(event);
//		}
	}
	
	/**
	 * Use only in tool main thread.
	 * 
	 * The default separator is System.getProperty("file.separator") for local
	 * workspaces, and '/' for remote workspaces.
	 * 
	 * @param newSeparator the new file separator, null sets the default separator
	 */
	final void controlSetFileSeparator(final char newSeparator) {
		final char oldSeparator= this.fileSeparator;
		if (newSeparator != 0) {
			this.fileSeparator= newSeparator;
		}
		else {
			this.fileSeparator= (isRemote()) ? '/' : File.separatorChar;
		}
	}
	
	protected final void controlSetWorkspaceDir(final IFileStore directory) {
		if ((this.workspaceDir != null) ? !this.workspaceDir.equals(directory) : directory != null) {
			this.workspaceDir= directory;
			this.properties.put("wd", directory);
			if (!this.isRefreshing) {
				firePropertiesChanged();
			}
		}
	}
	
	protected final void controlSetRemoteWorkspaceDir(final IPath toolPath) {
		this.remoteWorkspaceDirPath= toolPath;
		try {
			controlSetWorkspaceDir(toFileStore(toolPath));
		}
		catch (final CoreException e) {
			controlSetWorkspaceDir(null);
		}
	}
	
	
	private final void firePrompt(final Prompt prompt, final List<DebugEvent> eventCollection) {
		final DebugEvent event= new DebugEvent(ToolWorkspace.this, DebugEvent.CHANGE, DETAIL_PROMPT);
		event.setData(prompt);
		if (eventCollection != null) {
			eventCollection.add(event);
			return;
		}
		else {
			fireEvent(event);
		}
	}
	
	protected final void fireEvent(final DebugEvent event) {
		final DebugPlugin manager= DebugPlugin.getDefault();
		if (manager != null) {
			manager.fireDebugEventSet(new DebugEvent[] { event });
		}
	}
	
	public final void addPropertyListener(final Listener listener) {
		this.propertyListener.add(listener);
	}
	
	public final void removePropertyListener(final Listener listener) {
		this.propertyListener.remove(listener);
	}
	
	protected final void addPropertyChanged(final String property, final Object attr) {
		this.properties.put(property, attr);
	}
	
	protected final void firePropertiesChanged() {
		if (this.properties.isEmpty()) {
			return;
		}
		for (final Listener listener : this.propertyListener.toList()) {
			try {
				listener.propertyChanged(ToolWorkspace.this, this.properties);
			}
			catch (final Exception e) {
				NicoCorePlugin.logError(0, "An unexpected exception was thrown when notifying a tool workspace listener about changes.", e);
			}
		}
		this.properties.clear();
	}
	
	public ImList<IDynamicVariable> getStringVariables() {
		return this.stringVariables;
	}
	
	protected void dispose() {
	}
	
}
