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

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.variables.IStringVariable;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.internal.r.console.core.RObjectDB;
import org.eclipse.statet.internal.r.rdata.REnvironmentVar;
import org.eclipse.statet.internal.r.rdata.RReferenceVar;
import org.eclipse.statet.internal.r.rdata.VirtualMissingVar;
import org.eclipse.statet.nico.core.NicoVariables;
import org.eclipse.statet.nico.core.runtime.ConsoleService;
import org.eclipse.statet.nico.core.runtime.Prompt;
import org.eclipse.statet.nico.core.runtime.ToolWorkspace;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.pkgmanager.IRPkgChangeSet;
import org.eclipse.statet.r.core.pkgmanager.IRPkgManager;
import org.eclipse.statet.r.core.pkgmanager.IRPkgManager.Event;
import org.eclipse.statet.r.core.tool.IRConsoleService;
import org.eclipse.statet.r.nico.ICombinedRDataAdapter;
import org.eclipse.statet.r.nico.RWorkspaceConfig;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.RList;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.services.RService;


/**
 * R Tool Workspace
 */
public class RWorkspace extends ToolWorkspace {
	
	
	public static final int REFRESH_AUTO=                   IRConsoleService.AUTO_CHANGE;
	public static final int REFRESH_COMPLETE=               0x02;
	public static final int REFRESH_PACKAGES=               IRConsoleService.PACKAGE_CHANGE;
	
	
	public static final int RESOLVE_UPTODATE=               1 << 1;
	public static final int RESOLVE_FORCE=                  1 << 2;
	public static final int RESOLVE_RECURSIVE=              1 << 3;
	
	public static final int RESOLVE_INDICATE_NA=            1 << 5;
	
	
	public static final ImList<IStringVariable> ADDITIONAL_R_VARIABLES= ImCollections.<IStringVariable>newList(
			NicoVariables.SESSION_STARTUP_DATE_VARIABLE,
			NicoVariables.SESSION_STARTUP_TIME_VARIABLE,
			NicoVariables.SESSION_CONNECTION_DATE_VARIABLE,
			NicoVariables.SESSION_CONNECTION_TIME_VARIABLE,
			NicoVariables.SESSION_STARTUP_WD_VARIABLE );
	
	
	protected static final class Changes {
		
		private final int changeFlags;
		private final Set<RElementName> changedEnvirs;
		
		public Changes(final int changeFlags, final Set<RElementName> changedEnvirs) {
			this.changeFlags= changeFlags;
			this.changedEnvirs= changedEnvirs;
		}
		
	}
	
	
	private static RReferenceVar verifyVar(final @Nullable RElementName fullName,
			final ICombinedRDataAdapter r, final ProgressMonitor m) {
		if (fullName == null) {
			return null;
		}
		try {
			return (RReferenceVar) r.evalCombinedStruct(fullName, 0, RService.DEPTH_REFERENCE, m);
		}
		catch (final Exception e) {
			return null;
		}
	}
	
	
	private boolean rObjectDBEnabled;
	private RObjectDB rObjectDB;
	private boolean autoRefreshDirty;
	
	private IRPkgManager pkgManager;
	private IRPkgManager.Listener pkgManagerListener;
	
	private final HashSet<RElementName> changedEnvirs= new HashSet<>();
	
	
	public RWorkspace(final AbstractRController controller, final String remoteHost,
			final RWorkspaceConfig config) {
		super(  controller,
				new Prompt("> ", ConsoleService.META_PROMPT_DEFAULT),  //$NON-NLS-1$
				"\n", (char) 0,
				remoteHost);
		if (config != null) {
			this.rObjectDBEnabled= config.getEnableObjectDB();
			setAutoRefresh(config.getEnableAutoRefresh());
		}
		
		final REnv rEnv= getProcess().getREnv();
		if (rEnv != null) {
			this.pkgManager= RCore.getRPkgManager(rEnv);
			if (this.pkgManager != null) {
				this.pkgManagerListener= new IRPkgManager.Listener() {
					@Override
					public void handleChange(final Event event) {
						if ((event.pkgsChanged() & IRPkgManager.INSTALLED) != 0) {
							final IRPkgChangeSet changeSet= event.getInstalledPkgChangeSet();
							if (changeSet != null && !changeSet.getNames().isEmpty()) {
								final RObjectDB db= RWorkspace.this.rObjectDB;
								if (db != null) {
									db.handleRPkgChange(changeSet.getNames());
								}
							}
						}
					}
				};
				this.pkgManager.addListener(this.pkgManagerListener);
			}
		}
		
		controlBriefChanged(null, RWorkspace.REFRESH_COMPLETE);
	}
	
	
	@Override
	public RProcess getProcess() {
		return (RProcess) super.getProcess();
	}
	
	private AbstractRController getController() {
		return (AbstractRController) getProcess().getController();
	}
	
	@Override
	public IFileStore toFileStore(final IPath toolPath) throws CoreException {
		if (!toolPath.isAbsolute() && toolPath.getDevice() == null && "~".equals(toolPath.segment(0))) { //$NON-NLS-1$
			final AbstractRController controller= getController();
			if (controller != null) {
				final IPath homePath= createToolPath(controller.getProperty("R:file.~")); //$NON-NLS-1$
				if (homePath != null) {
					return super.toFileStore(homePath.append(toolPath.removeFirstSegments(1)));
				}
			}
			return null;
		}
		return super.toFileStore(toolPath);
	}
	
	@Override
	public IFileStore toFileStore(final String toolPath) throws CoreException {
		if (toolPath.startsWith("~/")) { //$NON-NLS-1$
			return toFileStore(createToolPath(toolPath));
		}
		return super.toFileStore(toolPath);
	}
	
	
	public boolean hasRObjectDB() {
		return (this.rObjectDBEnabled);
	}
	
	protected void enableRObjectDB(final boolean enable) {
		this.rObjectDBEnabled= enable;
		if (enable) {
			final AbstractRController controller= getController();
			if (controller != null) {
				controller.briefChanged(REFRESH_COMPLETE);
			}
		}
		else {
			this.rObjectDB= null;
		}
	}
	
	private int getStamp() {
		final AbstractRController controller= getController();
		return (controller != null) ? controller.getChangeStamp() : 0;
	}
	
	
	@Override
	protected void controlBriefChanged(final Object obj, final int flags) {
		if (obj instanceof Collection) {
			final Collection<?> collection = (Collection<?>) obj;
			for (final Object child : collection) {
				controlBriefChanged(child, flags);
			}
			return;
		}
		if (obj instanceof RElementName) {
			final RElementName name = (RElementName) obj;
			if (RElementName.isSearchScopeType(name.getType())) {
				this.changedEnvirs.add(name);
				return;
			}
		}
		super.controlBriefChanged(obj, flags);
	}
	
	protected Changes saveChanges() {
		return new Changes(getChangeFlags(),
				(!this.changedEnvirs.isEmpty()) ?
						(Set<RElementName>) this.changedEnvirs.clone() :
						Collections.EMPTY_SET );
	}
	
	protected void restoreChanges(final Changes changes) {
		super.controlBriefChanged(null, changes.changeFlags);
		this.changedEnvirs.addAll(changes.changedEnvirs);
	}
	
	private boolean hasBriefedChanges() {
		return (getChangeFlags() != 0 || !this.changedEnvirs.isEmpty());
	}
	
	@Override
	protected void clearBriefedChanges() {
		super.clearBriefedChanges();
		this.changedEnvirs.clear();
	}
	
	
	public List<? extends RProcessREnvironment> getRSearchEnvironments() {
		final RObjectDB db= this.rObjectDB;
		return (db != null) ? db.getSearchEnvs(): null;
	}
	
	private boolean checkResolve(final CombinedRElement resolved, final int resolve) {
		final int stamp;
		return ((resolve & RESOLVE_UPTODATE) == 0
						|| (resolved instanceof REnvironmentVar
								&& (stamp= getStamp()) != 0
								&& ((REnvironmentVar) resolved).getStamp() == stamp ));
	}
	
	private CombinedRElement filterResolve(final CombinedRElement resolved, final int resolve) {
		return ((resolve & RESOLVE_INDICATE_NA) == 0 && resolved instanceof VirtualMissingVar) ?
				null : resolved;
	}
	
	private CombinedRElement doResolve(final RObjectDB db,
			final RReference reference, final int resolve) {
		CombinedRElement resolved;
		
		resolved= db.getEnv(reference.getHandle());
		if (resolved != null) {
			if (checkResolve(resolved, resolve)) {
				return resolved;
			}
		}
		else if (reference instanceof CombinedRElement) {
			resolved= db.getByName(((CombinedRElement) reference).getElementName());
			if (resolved != null && checkResolve(resolved, resolve)) {
				return resolved;
			}
		}
		return null;
	}
	
	public CombinedRElement resolve(final RReference reference, final int resolve) {
		final RObjectDB db= this.rObjectDB;
		if (db != null) {
			return filterResolve(doResolve(db, reference, resolve), resolve);
		}
		return null;
	}
	
	public CombinedRElement resolve(final RElementName name, final int resolve) {
		final RObjectDB db= this.rObjectDB;
		if (db != null) {
			CombinedRElement resolved;
			
			resolved= db.getByName(name);
			if (resolved != null && checkResolve(resolved, resolve)) {
				return filterResolve(resolved, resolve);
			}
		}
		return null;
	}
	
	public boolean isNamespaceLoaded(final String name) {
		final RObjectDB db= this.rObjectDB;
		return (db != null && db.isNamespaceLoaded(name));
	}
	
	public boolean isUptodate(CombinedRElement element) {
		final AbstractRController controller= getController();
		if (controller != null) {
			if (element instanceof VirtualMissingVar) {
				final VirtualMissingVar var= (VirtualMissingVar) element;
				return (var.getSource() == controller.getTool()
						&& var.getStamp() == controller.getChangeStamp() );
			}
			while (element != null) {
				if (element.getRObjectType() == RObject.TYPE_ENVIRONMENT) {
					final REnvironmentVar var= (REnvironmentVar) element;
					return (var.getSource() == controller.getTool()
							&& var.getStamp() == controller.getChangeStamp() );
				}
				element= element.getModelParent();
			}
		}
		return false;
	}
	
	public boolean isNA(final CombinedRElement element) {
		return (element instanceof VirtualMissingVar);
	}
	
	
	public CombinedRElement resolve(final RReference reference, final int resolve,
			final int loadOptions, final ProgressMonitor m) throws StatusException {
		final AbstractRController controller= getController();
		if (controller == null || !(controller instanceof ICombinedRDataAdapter)) {
			return null;
		}
		
		RObjectDB db= this.rObjectDB;
		
		if (db != null && (resolve & RESOLVE_FORCE) == 0) {
			final CombinedRElement resolved= doResolve(db, reference, resolve);
			if (resolved != null) {
				return filterResolve(resolved, resolve);
			}
		}
		
		RReferenceVar ref= null;
		if (reference instanceof RReferenceVar) {
			ref= (RReferenceVar) reference;
			if (ref.getHandle() == 0 || !isUptodate(ref)) {
				ref= verifyVar(RModel.getFQElementName(ref),
						(ICombinedRDataAdapter) controller, m );
			}
		}
		if (ref == null) {
			return null;
		}
		
		if (db == null) {
			db= new RObjectDB(this, controller.getChangeStamp() - 1000,
					controller, m );
			this.rObjectDB= db;
		}
		else if (db.getLazyEnvsStamp() != controller.getChangeStamp()) {
			db.updateLazyEnvs(controller, m);
		}
		
		return db.resolve(ref, resolve, loadOptions,
				(ICombinedRDataAdapter) controller, m );
	}
	
	public CombinedRElement resolve(final RElementName name, final int resolve,
			final int loadOptions, final ProgressMonitor m) throws StatusException {
		final AbstractRController controller= getController();
		if (controller == null || !(controller instanceof ICombinedRDataAdapter)) {
			return null;
		}
		
		RObjectDB db= this.rObjectDB;
		
		if ((resolve & RESOLVE_FORCE) == 0 && db != null) {
			CombinedRElement resolved;
			
			resolved= db.getByName(name);
			if (resolved != null && checkResolve(resolved, resolve)) {
				return filterResolve(resolved, resolve);
			}
		}
		
		final RReferenceVar ref;
		if (name.getNextSegment() == null
				&& name.getType() == RElementName.SCOPE_NS ) {
			ref= new RReferenceVar(0, RObject.TYPE_ENVIRONMENT, RObject.CLASSNAME_ENVIRONMENT,
					null, name );
		}
		else {
			ref= verifyVar(name, (ICombinedRDataAdapter) controller, m);
			if (ref != null && db != null) {
				CombinedRElement resolved;
				
				resolved= db.getEnv(ref.getHandle());
				if (resolved != null && checkResolve(resolved, resolve)) {
					return filterResolve(resolved, resolve);
				}
			}
		}
		if (ref == null) {
			return null;
		}
		
		
		if (db == null) {
			db= new RObjectDB(this, controller.getChangeStamp() - 1000,
					controller, m );
			this.rObjectDB= db;
		}
		else if (db.getLazyEnvsStamp() != controller.getChangeStamp()) {
			db.updateLazyEnvs(controller, m);
		}
		
		return db.resolve(ref, resolve, loadOptions,
				(ICombinedRDataAdapter) controller, m );
	}
	
	
	public boolean isRObjectDBDirty() {
		return this.autoRefreshDirty;
	}
	
	@Override
	protected final void autoRefreshFromTool(final ConsoleService adapter,
			final ProgressMonitor m) throws StatusException {
		final AbstractRController controller= getController();
		if (hasBriefedChanges() || controller.isSuspended()) {
			refreshFromTool(controller, getChangeFlags(), m);
		}
	}
	
	@Override
	protected final void refreshFromTool(int options, final ConsoleService adapter,
			final ProgressMonitor m) throws StatusException {
		final AbstractRController controller= getController();
		if ((options & (REFRESH_AUTO | REFRESH_COMPLETE)) != 0) {
			options |= getChangeFlags();
		}
		refreshFromTool(controller, options, m);
	}
	
	protected void refreshFromTool(final AbstractRController controller, final int options,
			final ProgressMonitor m) throws StatusException {
		m.beginSubTask("Update Workspace Data");
		if (controller.getTool().isProvidingFeatureSet(RConsoleTool.R_DATA_FEATURESET_ID)) {
			final IRDataAdapter r= (IRDataAdapter) controller;
			updateWorkspaceDir(r, m);
			updateOptions(r, m);
			if (this.rObjectDBEnabled) {
				final Set<RElementName> elements= this.changedEnvirs;
				if ( ((options & REFRESH_COMPLETE) != 0)
						|| ( ((((options & REFRESH_AUTO)) != 0) || !elements.isEmpty()
								|| controller.isSuspended() )
								&& isAutoRefreshEnabled() ) ) {
					updateREnvironments(elements, ((options & REFRESH_COMPLETE) != 0), r, m);
					clearBriefedChanges();
				}
			}
			else {
				clearBriefedChanges();
			}
		}
		else {
			clearBriefedChanges();
		}
		
		final boolean dirty= !isAutoRefreshEnabled() && hasBriefedChanges();
		if (dirty != this.autoRefreshDirty) {
			this.autoRefreshDirty= dirty;
			addPropertyChanged("RObjectDB.dirty", dirty);
		}
	}
	
	private void updateWorkspaceDir(
			final IRDataAdapter r, final ProgressMonitor m) throws StatusException {
		final RObject rWd= r.evalData("getwd()", m); //$NON-NLS-1$
		if (RDataUtils.isSingleString(rWd)) {
			final String wd= rWd.getData().getChar(0);
			if (!isRemote()) {
				controlSetWorkspaceDir(EFS.getLocalFileSystem().getStore(createToolPath(wd)));
			}
			else {
				controlSetRemoteWorkspaceDir(createToolPath(wd));
			}
		}
	}
	
	private void updateOptions(
			final IRDataAdapter r, final ProgressMonitor m) throws StatusException {
		final RList rOptions= (RList) r.evalData("options(\"prompt\", \"continue\")", m); //$NON-NLS-1$
		final RObject rPrompt= rOptions.get("prompt"); //$NON-NLS-1$
		if (RDataUtils.isSingleString(rPrompt)) {
			if (!rPrompt.getData().isNA(0)) {
				((AbstractRController) r).setDefaultPromptTextL(rPrompt.getData().getChar(0));
			}
		}
		final RObject rContinue= rOptions.get("continue"); //$NON-NLS-1$
		if (RDataUtils.isSingleString(rContinue)) {
			if (!rContinue.getData().isNA(0)) {
				((AbstractRController) r).setContinuePromptText(rContinue.getData().getChar(0));
			}
		}
	}
	
	private void updateREnvironments(final Set<RElementName> envirs, boolean force,
			final IRDataAdapter r, final ProgressMonitor m) throws StatusException {
		if (!(r instanceof ICombinedRDataAdapter)) {
			return;
		}
		
		final AbstractRController controller= getController();
		
//		final long time= System.nanoTime();
//		System.out.println(controller.getCounter() + " update");
		
		final RObjectDB previous= this.rObjectDB;
		force|= (previous == null || previous.getSearchEnvs() == null);
		if (!force && previous.getSearchEnvsStamp() == controller.getChangeStamp() && envirs.isEmpty()) {
			return;
		}
		final RObjectDB db= new RObjectDB(this, controller.getChangeStamp(), controller, m);
		final List<REnvironmentVar> updateEnvs= db.update(
				envirs, previous, force,
				(ICombinedRDataAdapter) r, m );
		
		if (m.isCanceled()) {
			return;
		}
		this.rObjectDB= db;
		addPropertyChanged("REnvironments", updateEnvs);
		
//		System.out.println("RSearch Update: " + (System.nanoTime() - time));
//		System.out.println("count: " + db.getSearchEnvsElementCount());
	}
	
	@Override
	protected void dispose() {
		if (this.pkgManagerListener != null) {
			this.pkgManager.removeListener(this.pkgManagerListener);
			this.pkgManagerListener= null;
		}
		
		super.dispose();
		this.rObjectDB= null;
	}
	
}
