/*=============================================================================#
 # Copyright (c) 2015, 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.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.status.Status;

import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.rj.data.RReference;


public class LoadReferencesUtil {
	
	
	public static final int MAX_EXPLICITE_WAIT= 250;
	public static final int MAX_AUTO_WAIT= 100;
	
	
	private class LoadRunnable extends LoadReferenceRunnable implements Runnable {
		
		public LoadRunnable(final RReference reference, final RProcess tool,
				final int stamp, final String cause) {
			super(reference, tool, stamp, cause);
			setFinishRunnable(this);
		}
		
		public LoadRunnable(final RElementName name, final RProcess tool,
				final int stamp, final String cause) {
			super(name, tool, stamp, cause);
			setFinishRunnable(this);
		}
		
		
		@Override
		public void run() {
			taskFinished(this);
		}
		
	}
	
	
	private final RProcess tool;
	
	private final Map<Object, LoadRunnable> resolveTasks= new HashMap<>();
	private final AtomicInteger resolveTasksScheduled= new AtomicInteger();
	
	private long waitMillis;
	
	private List<CombinedRElement> resolvedElements;
	
	
	public LoadReferencesUtil(final RProcess tool, final long waitTimeout) {
		if (tool == null) {
			throw new NullPointerException("tool"); //$NON-NLS-1$
		}
		this.tool= tool;
		this.waitMillis= waitTimeout;
	}
	
	
	public long getWaitTimeout() {
		return this.waitMillis;
	}
	
	public void setWaitTimeout(final long millis) {
		this.waitMillis= millis;
	}
	
	public CombinedRElement resolve(final RReference reference, final int loadOptions) {
		if (reference instanceof CombinedRElement) {
			final RProcess elementProcess= LoadReferenceRunnable.findRProcess(
					(CombinedRElement) reference );
			if (elementProcess != this.tool) {
				return null;
			}
		}
		else {
			return null;
		}
		
		final Long key= Long.valueOf(reference.getHandle());
		LoadRunnable task= this.resolveTasks.get(key);
		if (task != null) {
			final int currentOptions= task.getLoadOptions();
			if ((currentOptions & loadOptions) == loadOptions) {
				return null;
			}
			synchronized (task) {
				if (!task.isStarted()) {
					task.setLoadOptions(currentOptions | loadOptions);
					return null;
				}
			}
		}
		task= new LoadRunnable(reference, this.tool, 0, "Content Assist");
		this.resolveTasks.put(key, task);
		
		return schedule(task);
	}
	
	public CombinedRElement resolve(final RElementName name, final int loadOptions) {
		final RElementName key= name;
		LoadRunnable task= this.resolveTasks.get(key);
		if (task != null) {
			final int currentOptions= task.getLoadOptions();
			if ((currentOptions & loadOptions) == loadOptions) {
				return task.getResolvedElement();
			}
			synchronized (task) {
				if (!task.isStarted()) {
					task.setLoadOptions(currentOptions | loadOptions);
					return null;
				}
			}
		}
		
		if (!LoadReferenceRunnable.isAccessAllowed(name, this.tool.getWorkspaceData())) {
			return null;
		}
		
		task= new LoadRunnable(name, this.tool, 0, "Content Assist");
		this.resolveTasks.put(key, task);
		
		return schedule(task);
	}
	
	private CombinedRElement schedule(final LoadRunnable task) {
		synchronized (task) {
			final long startTime= System.nanoTime();
			if (task.getTool().getQueue().addHot(task).getSeverity() == Status.OK) {
				try {
					final long wait= this.waitMillis;
					if (wait > 0) {
						task.wait(wait);
					}
					if (task.isFinished()) {
						return task.getResolvedElement();
					}
					else {
						this.resolveTasksScheduled.incrementAndGet();
						return null;
					}
				}
				catch (final InterruptedException e) {
					task.cancel();
				}
				finally {
					this.waitMillis-= TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime); 
				}
			}
			return null;
		}
	}
	
	protected void taskFinished(final LoadRunnable runnable) {
		final CombinedRElement element= runnable.getResolvedElement();
		if (element != null) {
			if (this.resolvedElements == null) {
				this.resolvedElements= new ArrayList<>();
			}
			this.resolvedElements.add(element);
		}
		
		if (this.resolveTasksScheduled.decrementAndGet() == 0) {
			allFinished((this.resolvedElements != null) ?
					ImCollections.toList(this.resolvedElements) :
					ImCollections.<CombinedRElement>emptyList() );
		}
	}
	
	protected void allFinished(final ImList<CombinedRElement> resolvedElements) {
	}
	
}
