/*=============================================================================#
 # 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.nico.core.runtime;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.osgi.util.NLS;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.InfoStatus;
import org.eclipse.statet.jcommons.status.OkStatus;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.ts.core.RunnableStatus;
import org.eclipse.statet.jcommons.ts.core.SystemRunnable;
import org.eclipse.statet.jcommons.ts.core.ToolQueue;
import org.eclipse.statet.jcommons.ts.core.ToolRunnable;

import org.eclipse.statet.internal.nico.core.Messages;
import org.eclipse.statet.nico.core.NicoCore;


/**
 * Queue with ToolRunnable waiting to be processed by the tool/controller.
 * 
 * Usage: You get your queue via accessor of the ToolProcess.
 * 
 * DebugEvents for a lifecycle of an entry:<pre>
 *                       CHANGE (CONTENT)
 *                       [ENTRIES_ADDED]
 *                             |
 *        +--------------------+---------------------+
 *        |                    |                     |
 *        |                    |              CHANGE (CONTENT)
 *        |                    |          [ENTRY_START_PROCESSING]
 *  CHANGE (CONTENT)           |                     |
 *  [ENTRIES_DELETE]           |              CHANGE (CONTENT)
 *                             |          [ENTRY_FINISH_PROCESSING]
 *                         TERMINATE
 *                    [ENTRIES_ABANDONED]
 * </pre>
 * The events of this type are sended by the queue (source element).
 * 
 */
@NonNullByDefault
public final class Queue implements ToolQueue {
	
	
	public static final byte INIT_STATE= 1;
	public static final byte PROCESSING_STATE= 2;
	public static final byte IDLING_STATE= 3;
	public static final byte PAUSED_STATE= 5;
	public static final byte TERMINATED_STATE= 6;
	
	
	/**
	 * Constant for detail of a DebugEvent, sending the complete queue.
	 * This does not signalising, that the queue has changed.
	 * <p>
	 * The queue entries (<code>List&lt;ToolRunnable&gt;</code>) are attached as
	 * data to this event. The source of the event is the ToolProcess.
	 * <p>
	 * Usage: Events of this type are sended by the ToolProcess/its queue.
	 * The constant is applicable for DebugEvents of kind
	 * <code>MODEL_SPECIFIC</code>.</p>
	 */
	public static final int QUEUE_INFO= 1;
	
	public static final int STATE_REQUEST= 5;
	
	
	/**
	 * TaskDelta for events of the queue.
	 * 
	 * Type is a event type of {@link ToolRunnable} events
	 */
	public static final class TaskDelta {
		
		public final int type;
		public final int position;
		
		/**
		 * One or multiple runnable effected by this event.
		 * STARTING and FINISHING events have always only a single item.
		 */
		public final ImList<ToolRunnable> data;
		
		private TaskDelta(final int type, final int position, final ImList<ToolRunnable> data) {
			this.type= type;
			this.position= position;
			this.data= data;
		}
		
	}
	
	public static final boolean isStateChange(final DebugEvent event) {
		return (event.getKind() == DebugEvent.CHANGE && event.getDetail() == DebugEvent.STATE);
	}
	
	public static final boolean isStateRequest(final DebugEvent event) {
		return (event.getKind() == DebugEvent.MODEL_SPECIFIC && event.getDetail() == STATE_REQUEST);
	}
	
	public static final class StateDelta {
		
		public final byte oldState;
		public final byte newState;
		
		private StateDelta(final byte oldState, final byte newState) {
			this.oldState= oldState;
			this.newState= newState;
		}
		
	}
	
	private static final int toRequestState(final int state) {
		return (state == IDLING_STATE) ? PROCESSING_STATE : state;
	}
	
	
	public static final int IF_ABSENT= 1 << 0;
	
	
	private static class RunnableInfoStatus extends InfoStatus implements RunnableStatus {
		
		private final ToolRunnable runnable;
		
		public RunnableInfoStatus(final int code, final String message, final ToolRunnable runnable) {
			super(NicoCore.BUNDLE_ID, code, message);
			this.runnable= runnable;
		}
		
		@Override
		public ToolRunnable getRunnable() {
			return this.runnable;
		}
		
	}
	
	private static class RunnableOkStatus extends OkStatus implements RunnableStatus {
		
		private final ToolRunnable runnable;
		
		public RunnableOkStatus(final String message, final ToolRunnable runnable) {
			super(NicoCore.BUNDLE_ID, "OK");
			this.runnable= runnable;
		}
		
		@Override
		public ToolRunnable getRunnable() {
			return this.runnable;
		}
		
	}
	
	
	private static final Status ADDED_STATUS= new OkStatus(NicoCore.BUNDLE_ID, "Added.");
	
	public static final Status ALREADY_PRESENT_STATUS= new InfoStatus(NicoCore.BUNDLE_ID, "Already in queue.");
	
	
	private static ToolRunnable checkRunnable(final @Nullable ToolRunnable runnable) {
		if (runnable == null) {
			throw new NullPointerException("runnable"); //$NON-NLS-1$
		}
		return runnable;
	}
	
	private static ImList<ToolRunnable> checkRunnableList(final @Nullable ToolRunnable runnable) {
		if (runnable == null) {
			throw new NullPointerException("runnable"); //$NON-NLS-1$
		}
		return ImCollections.newList(runnable);
	}
	
	private static ImList<ToolRunnable> checkRunnableList(final @Nullable List<ToolRunnable> runnables) {
		if (runnables == null) {
			throw new NullPointerException("runnables"); //$NON-NLS-1$
		}
		final ImList<ToolRunnable> finalRunnables= ImCollections.toList(runnables);
		final int i= finalRunnables.indexOf(null);
		if (i >= 0) {
			throw new NullPointerException("runnable[" + i + ']'); //$NON-NLS-1$
		}
		return finalRunnables;
	}
	
	
	static final int RUN_NONE= -2;
	static final int RUN_SUSPEND= -1;
	static final int RUN_CONTROL= 1;
	static final int RUN_HOT= 2;
	static final int RUN_OTHER= 3;
	static final int RUN_DEFAULT= 4;
	
	
	private static class RankedItem {
		
		final ToolRunnable runnable;
		final int rank;
		
		public RankedItem(final ToolRunnable runnable, final int rank) {
			this.runnable= runnable;
			this.rank= rank;
		}
		
		
		@Override
		public int hashCode() {
			return this.runnable.hashCode();
		}
		
		@Override
		public boolean equals(final Object obj) {
			if (this == obj) {
				return true;
			}
			final RankedItem other= (RankedItem) obj;
			return (this.runnable.equals(other.runnable) );
		}
		
	}
	
	
	public static interface Section {
		
	}
	
	private static abstract class SubQueue implements Section {
		
		protected final LinkedList<ToolRunnable> list= new LinkedList<>();
		
		private @Nullable SubQueue next;
		
		private boolean state;
		
		
		public abstract int getAllSize();
		
		public abstract int getAll(final ToolRunnable[] array, final int i);
		
		public int getStartIdx() {
			int idx= 0;
			SubQueue next= this.next;
			while (next != null) {
				idx+= next.getAllSize();
				next= next.next;
			}
			return idx;
		}
		
		public int getAppendIdx() {
			return getStartIdx() + this.list.size();
		}
		
		public void append(final ImList<ToolRunnable> runnables) {
			if (runnables.size() == 1) {
				this.list.add(runnables.get(0));
			}
			else {
				this.list.addAll(runnables);
			}
		}
		
		public void append(final ToolRunnable runnable) {
			this.list.add(runnable);
		}
		
		public void dispose() {
			this.state= true;
			
			this.list.clear();
			
			this.next= null;
		}
		
		public boolean isDispose() {
			return this.state;
		}
		
	}
	
	private static final class TopLevelQueue extends SubQueue {
		
		
		public TopLevelQueue() {
		}
		
		
		@Override
		public int getAllSize() {
			return this.list.size();
		}
		
		@Override
		public int getAll(final ToolRunnable[] array, int i) {
			for (final ToolRunnable runnable : this.list) {
				array[i++]= runnable;
			}
			return i;
		}
		
	}
	
	private static final class InsertQueue extends SubQueue {
		
		protected final ToolRunnable insertRunnable;
		
		
		public InsertQueue(final ToolRunnable insertRunnable) {
			this.insertRunnable= insertRunnable;
		}
		
		
		@Override
		public int getAllSize() {
			return this.list.size() + 1;
		}
		
		@Override
		public int getAll(final ToolRunnable[] array, int i) {
			for (final ToolRunnable runnable : this.list) {
				array[i++]= runnable;
			}
			array[i++]= this.insertRunnable;
			return i;
		}
		
	}
	
	private final List<SubQueue> sectionStack= new ArrayList<>();
	private final SubQueue topLevelSection; // sectionStack.first
	private SubQueue currentSection; // sectionStack.last
	private @Nullable ImList<ToolRunnable> singleIOCache= null;
	
	private final Deque<ImList<ToolRunnable>> finishedExpected= new ArrayDeque<>();
	private final List<DebugEvent> eventList= new ArrayList<>(5);
	
	private final ToolProcess process;
	
	private boolean resetOnIdle= true;
	private final List<RankedItem> onIdleList= new ArrayList<>();
	private final LinkedList<ToolRunnable> currentIdleList= new LinkedList<>();
	
	private final LinkedList<ToolRunnable> hotList= new LinkedList<>();
	
	private byte state;
	private byte stateRequest= PROCESSING_STATE;
	
	
	Queue(final ToolProcess process) {
		this.process= process;
		
		this.topLevelSection= new TopLevelQueue();
		this.sectionStack.add(this.topLevelSection);
		this.currentSection= this.topLevelSection;
	}
	
	
	private final Status acceptSubmit(final ToolStatus toolStatus) {
		if (toolStatus == ToolStatus.TERMINATED) {
			return new ErrorStatus(NicoCore.BUNDLE_ID, -1,
					NLS.bind(Messages.ToolController_ToolTerminated_message, this.process.getLabel(0)),
					null );
		}
		return ADDED_STATUS;
	}
	
	private final Status acceptSubmit(final ToolStatus toolStatus, final SubQueue section) {
		if (toolStatus == ToolStatus.TERMINATED) {
			return new ErrorStatus(NicoCore.BUNDLE_ID, -1,
					NLS.bind(Messages.ToolController_ToolTerminated_message, this.process.getLabel(0)),
					null );
		}
		if (section.isDispose()) {
			return new ErrorStatus(NicoCore.BUNDLE_ID, -1,
					NLS.bind(Messages.ToolController_QueueSectionTerminated_message, this.process.getLabel(0)),
					null );
		}
		return ADDED_STATUS;
	}
	
	public synchronized void sendElements() {
		checkIOCache();
		final ImList<ToolRunnable> runnables= internal_createCompleteList();
		final DebugEvent event= new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, QUEUE_INFO);
		event.setData(runnables);
		this.eventList.add(event);
		internal_fireEvents();
	}
	
	public Section getTopLevelSection() {
		return this.topLevelSection;
	}
	
	public synchronized Section getCurrentSection() {
		return this.currentSection;
	}
	
	
	public synchronized int getCurrentSize() {
		if (this.singleIOCache != null) {
			return 1;
		}
		return this.currentSection.list.size();
	}
	
	/**
	 * Submits the runnable for the tool.
	 * <p>
	 * The runnable will be added to the queue and will be run, if it's its turn.
	 * 
	 * @param runnable the runnable to add
	 * @return the status of the queue operation.
	 */
	@Override
	public Status add(final ToolRunnable runnable) {
		final ImList<ToolRunnable> checkedRunnables= checkRunnableList(runnable);
		
		return doAdd(checkedRunnables, null);
	}
	
	/**
	 * Submits the runnables for the tool.
	 * <p>
	 * The runnables will be added en block to the queue and will be runned, if it's its turn.
	 * 
	 * @param runnables the runnables to add.
	 * @return the status of the queue operation.
	 */
	public Status add(final List<ToolRunnable> runnables) {
		final ImList<ToolRunnable> checkedRunnables= checkRunnableList(runnables);
		
		return doAdd(checkedRunnables, null);
	}
	
	/**
	 * Submits the runnable for the tool.
	 * <p>
	 * The runnable will be added to the queue in the specified section
	 * and will be run, if it's its turn.
	 * 
	 * @param runnable the runnable to add
	 * @param section where to add the runnable, <code>null</code> for current section
	 * @param strategy flags {@link #IF_ABSENT}
	 * @return the status of the queue operation.
	 */
	public Status add(final ToolRunnable runnable,
			final @Nullable Section section, final int strategy) {
		final ToolRunnable checkedRunnable= checkRunnable(runnable);
		
		return doAdd(checkedRunnable, (SubQueue) section, strategy);
	}
	
	/**
	 * Submits the runnables for the tool.
	 * <p>
	 * The runnables will be added en block to the queue in the specified section
	 * and will be runned, if it's its turn.
	 * 
	 * @param runnables the runnables to add.
	 * @param section where to add the runnabler, <code>null</code> for current section
	 * @return the status of the queue operation.
	 */
	public Status add(final List<ToolRunnable> runnables,
			final @Nullable Section section) {
		final ImList<ToolRunnable> checkedRunnables= checkRunnableList(runnables);
		
		return doAdd(checkedRunnables, (SubQueue) section);
	}
	
	private synchronized Status doAdd(final ImList<ToolRunnable> runnables,
			@Nullable SubQueue section) {
		if (section == null) {
			section= this.currentSection;
		}
		
		final ToolStatus toolStatus= this.process.getToolStatus();
		final Status status= acceptSubmit(toolStatus, section);
		if (status.getSeverity() < Status.ERROR) {
			if (toolStatus.isWaiting()) {
				internal_add(runnables, section, true);
				notifyAll();
			}
			else {
				internal_add(runnables, section, false);
			}
		}
		return status;
	}
	
	private synchronized Status doAdd(final ToolRunnable runnable,
			@Nullable SubQueue section, final int strategy) {
		if (section == null) {
			section= this.currentSection;
		}
		
		final ToolStatus toolStatus= this.process.getToolStatus();
		final Status status= acceptSubmit(toolStatus, section);
		if (status.getSeverity() < Status.ERROR) {
			if (strategy != 0) {
				checkIOCache();
				
				int idx;
				if ((strategy & IF_ABSENT) != 0 && (idx= section.list.indexOf(runnable)) >= 0) {
					return new RunnableInfoStatus(0, ALREADY_PRESENT_STATUS.getMessage(),
							section.list.get(idx) );
				}
			}
			
			if (toolStatus.isWaiting()) {
				internal_add(ImCollections.newList(runnable), section, true);
				notifyAll();
			}
			else {
				internal_add(ImCollections.newList(runnable), section, false);
			}
			return new RunnableOkStatus(ADDED_STATUS.getMessage(), runnable);
		}
		return status;
	}
	
	@Override
	public void remove(final ToolRunnable runnable) {
		final ImList<ToolRunnable> checkedRunnables= checkRunnableList(runnable);
		
		synchronized (this) {
			internal_remove(checkedRunnables);
			
			internal_fireEvents();
		}
	}
	
	public void remove(final List<ToolRunnable> runnables) {
		final ImList<ToolRunnable> checkedRunnables= checkRunnableList(runnables);
		
		synchronized (this) {
			internal_remove(checkedRunnables);
			
			internal_fireEvents();
		}
	}
	
	public void move(final ImList<ToolRunnable> runnables, final Queue to) {
		final ImList<ToolRunnable> checkedRunnables= checkRunnableList(runnables);
		if (to == null) {
			throw new NullPointerException("to"); //$NON-NLS-1$
		}
		
		final ImList<ToolRunnable> finalRunnables;
		synchronized (this) {
			finalRunnables= internal_moveFrom(checkedRunnables);
		}
		
		synchronized (to) {
			to.internal_moveTo(finalRunnables, to.currentSection);
			
			to.notifyAll();
		}
	}
	
	public void moveAll(final Queue to) {
		if (to == null) {
			throw new NullPointerException("to"); //$NON-NLS-1$
		}
		final ImList<ToolRunnable> finalRunnables;
		synchronized (this) {
			checkIOCache();
			
			{	final List<ToolRunnable> removed= new ArrayList<>(internal_getCompleteSize());
				for (final Iterator<ToolRunnable> iter= this.topLevelSection.list.iterator(); iter.hasNext();) {
					final ToolRunnable runnable= iter.next();
					if (runnable.changed(ToolRunnable.MOVING_FROM, this.process)) {
						iter.remove();
						removed.add(runnable);
					}
				}
				finalRunnables= ImCollections.toList(removed);
			}
			
			addContentChangeEvent(new TaskDelta(ToolRunnable.MOVING_FROM, -1, finalRunnables));
			
			internal_fireEvents();
		}
		
		synchronized (to) {
			to.internal_moveTo(finalRunnables, to.topLevelSection);
			
			to.notifyAll();
		}
	}
	
	public Status addOnIdle(final SystemRunnable runnable, final int rank) {
		final ToolRunnable checkedRunnable= checkRunnable(runnable);
		
		synchronized (this) {
			final ToolStatus toolStatus= this.process.getToolStatus();
			final Status status= acceptSubmit(toolStatus);
			if (status.getSeverity() < Status.ERROR) {
				final RankedItem item= new RankedItem(checkedRunnable, rank);
				
				int idx= this.onIdleList.indexOf(item);
				if (idx >= 0 && this.onIdleList.get(idx).rank != rank) {
					this.onIdleList.remove(idx);
					if (!this.resetOnIdle) {
						this.currentIdleList.remove(item.runnable);
					}
					idx= -1;
				}
				if (idx < 0) {
					idx= 0;
					for (; idx < this.onIdleList.size(); idx++) {
						if (this.onIdleList.get(idx).rank > rank) {
							break;
						}
					}
					this.onIdleList.add(idx, item);
					
					if (!this.resetOnIdle) {
						if (idx == this.onIdleList.size() - 1) { // last
							this.currentIdleList.add(item.runnable);
						}
						else {
							final RankedItem next= this.onIdleList.get(idx + 1);
							final int nextIdx= this.currentIdleList.indexOf(next.runnable);
							if (nextIdx >= 0) {
								this.currentIdleList.add(nextIdx, item.runnable);
							}
						}
					}
				}
				notifyAll();
			}
			return status;
		}
	}
	
	public void removeOnIdle(final ToolRunnable runnable) {
		final ToolRunnable checkedRunnable= checkRunnable(runnable);
		
		synchronized (this) {
			this.onIdleList.remove(new RankedItem(checkedRunnable, 0));
			this.currentIdleList.remove(runnable);
		}
	}
	
	@Override
	public boolean isHotSupported() {
		return true;
	}
	
	@Override
	public Status addHot(final ToolRunnable runnable) {
		return addHot(runnable, 0);
	}
	
	public Status addHot(final ToolRunnable runnable, final int strategy) {
		final ToolRunnable checkedRunnable= checkRunnable(runnable);
		
		synchronized (this) {
			final ToolStatus toolStatus= this.process.getToolStatus();
			final Status status= acceptSubmit(toolStatus);
			if (status.getSeverity() < Status.ERROR) {
				if ((strategy & IF_ABSENT) != 0) {
					if (this.hotList.contains(checkedRunnable)) {
						return ALREADY_PRESENT_STATUS;
					}
				}
				this.hotList.add(checkedRunnable);
				if (this.hotList.size() > 0) {
					notifyAll();
					final ToolController controller= this.process.getController();
					if (controller != null) {
						controller.scheduleHotMode();
					}
				}
			}
			return status;
		}
	}
	
	@Override
	public void removeHot(final ToolRunnable runnable) {
		final ToolRunnable checkedRunnable= checkRunnable(runnable);
		synchronized (this) {
			if (this.hotList.remove(checkedRunnable)) {
				runnable.changed(ToolRunnable.REMOVING_FROM, this.process);
			}
		}
	}
	
	
	private void internal_add(final ImList<ToolRunnable> runnables, final SubQueue section,
			final boolean allowCache) {
		if (allowCache && this.singleIOCache == null
				&& runnables.size() == 1
				&& section == this.currentSection && this.currentSection.list.isEmpty() ) {
			this.singleIOCache= runnables;
			return;
		}
		
		checkIOCache();
		
		final int idx= section.getAppendIdx();
		section.append(runnables);
		addContentChangeEvent(new TaskDelta(ToolRunnable.ADDING_TO, idx, runnables));
		
		internal_fireEvents();
	}
	
	private void internal_remove(final ImList<ToolRunnable> runnables) {
		checkIOCache();
		
		final ImList<ToolRunnable> finalRunnables;
		{	final List<ToolRunnable> removed= new ArrayList<>(runnables.size());
			
			ITER_RUNNABLE: for (final ToolRunnable runnable : runnables) {
				for (int iSection= this.sectionStack.size() - 1; iSection >= 0; iSection--) {
					final SubQueue section= this.sectionStack.get(iSection);
					final int idx= section.list.indexOf(runnable);
					if (idx >= 0) {
						if (runnable.changed(ToolRunnable.REMOVING_FROM, this.process)) {
							section.list.remove(idx);
							removed.add(runnable);
						}
						continue ITER_RUNNABLE;
					}
				}
			}
			finalRunnables= ImCollections.toList(removed);
		}
		
		addContentChangeEvent(new TaskDelta(ToolRunnable.REMOVING_FROM, -1, finalRunnables));
		
		internal_fireEvents();
	}
	
	private ImList<ToolRunnable> internal_moveFrom(final ImList<ToolRunnable> runnables) {
		checkIOCache();
		
		final ImList<ToolRunnable> finalRunnables;
		{	final List<ToolRunnable> removed= new ArrayList<>(runnables.size());
			
			ITER_RUNNABLE: for (final ToolRunnable runnable : runnables) {
				for (int iSection= this.sectionStack.size() - 1; iSection >= 0; iSection--) {
					final SubQueue section= this.sectionStack.get(iSection);
					final int idx= section.list.indexOf(runnable);
					if (idx >= 0) {
						if (runnable.changed(ToolRunnable.MOVING_FROM, this.process)) {
							section.list.remove(idx);
							removed.add(runnable);
						}
						continue ITER_RUNNABLE;
					}
				}
			}
			finalRunnables= ImCollections.toList(removed);
		}
		
		addContentChangeEvent(new TaskDelta(ToolRunnable.MOVING_FROM, -1, finalRunnables));
		
		internal_fireEvents();
		
		return finalRunnables;
	}
	
	private void internal_moveTo(final ImList<ToolRunnable> runnables, final SubQueue section) {
		checkIOCache();
		
		final int idx= section.getAppendIdx();
		section.append(runnables);
		addContentChangeEvent(new TaskDelta(ToolRunnable.MOVING_TO, idx, runnables));
		
		internal_fireEvents();
	}
	
	
	Section internal_addInsert(final ToolRunnable runnable) {
		assert (runnable != null);
		
		checkIOCache();
		
		final SubQueue section= new InsertQueue(runnable);
		this.sectionStack.add(section);
		this.currentSection.next= section;
		this.currentSection= section;
		addContentChangeEvent(new TaskDelta(ToolRunnable.ADDING_TO, 0, ImCollections.newList(runnable)));
		
		internal_resetOnIdle();
		
		internal_fireEvents();
		
		return section;
	}
	
	void internal_removeInsert(final Section section) {
		assert (section != null);
		
		checkIOCache();
		
		final int sectionIdx= this.sectionStack.indexOf(section);
		if (sectionIdx < 0) {
			return;
		}
		if (sectionIdx == 0) {
			throw new IllegalArgumentException();
		}
		
		final ImList<ToolRunnable> finalRunnables;
		{	final ToolRunnable[] runnables= new @NonNull ToolRunnable[
					internal_getSize(sectionIdx, this.sectionStack.size()) ];
			int i= 0;
			for (int iSection= this.sectionStack.size() - 1; iSection >= sectionIdx; iSection--) {
				final SubQueue removedSection= this.sectionStack.remove(iSection);
				i= removedSection.getAll(runnables, i);
				removedSection.dispose();
			}
			this.currentSection= this.sectionStack.get(this.sectionStack.size() - 1);
			this.currentSection.next= null;
			
			finalRunnables= ImCollections.newList(runnables);
		}
		for (final ToolRunnable runnable : finalRunnables) {
//			runnable.changed(ToolRunnable.BEING_ABANDONED, this.process);
			if (!runnable.changed(ToolRunnable.REMOVING_FROM, this.process)) {
				runnable.changed(ToolRunnable.BEING_ABANDONED, this.process);
			}
		}
		
		addContentChangeEvent(new TaskDelta(ToolRunnable.REMOVING_FROM, -1, finalRunnables));
		
		internal_resetOnIdle();
		
		internal_fireEvents();
	}
	
	
	void internal_scheduleIdle(final ToolRunnable runnable) {
		final ToolRunnable checkedRunnable= checkRunnable(runnable);
		
		this.currentIdleList.add(checkedRunnable);
	}
	
	void internal_removeIdle(final ToolRunnable runnable) {
		final ToolRunnable checkedRunnable= checkRunnable(runnable);
		
		this.currentIdleList.remove(checkedRunnable);
	}
	
	
	void internal_check() {
		checkIOCache();
		internal_fireEvents();
	}
	
	void internal_resetOnIdle() {
		this.resetOnIdle= true;
	}
	
	private void internal_resetIdleList() {
		this.resetOnIdle= false;
		this.currentIdleList.clear();
		for (int i= 0; i < this.onIdleList.size(); i++) {
			this.currentIdleList.add(this.onIdleList.get(i).runnable);
		}
	}
	
	int internal_next() {
		if (!this.hotList.isEmpty()) {
			return RUN_HOT;
		}
		final ToolRunnable runnable;
		if (this.singleIOCache != null) {
			runnable= this.singleIOCache.get(0);
		}
		else if (!this.currentSection.list.isEmpty()) {
			runnable= this.currentSection.list.peekFirst();
		}
		else {
			if (this.resetOnIdle) {
				internal_resetIdleList();
			}
			if (!this.currentIdleList.isEmpty()) {
				runnable= this.currentIdleList.peekFirst();
			}
			else {
				return RUN_NONE;
			}
		}
		return (runnable instanceof SystemRunnable) ?
				RUN_OTHER : RUN_DEFAULT;
	}
	
	/** After check with {@link #internal_next()} */
	ToolRunnable internal_poll() {
		final @NonNull ImList<ToolRunnable> finalRunnable;
		if (this.singleIOCache != null) {
			finalRunnable= this.singleIOCache;
			final int idx= this.currentSection.getAppendIdx();
			addContentChangeEvent(new TaskDelta(ToolRunnable.ADDING_TO, idx, finalRunnable));
			this.singleIOCache= null;
			internal_resetOnIdle();
		}
		else if (!this.currentSection.list.isEmpty()) {
			finalRunnable= ImCollections.newList(this.currentSection.list.pollFirst());
			internal_resetOnIdle();
		}
		else {
			finalRunnable= ImCollections.newList(this.currentIdleList.pollFirst());
		}
		addContentChangeEvent(new TaskDelta(ToolRunnable.STARTING, -1, finalRunnable));
		
		internal_fireEvents();
		this.finishedExpected.push(finalRunnable);
		return finalRunnable.get(0);
	}
	
	boolean internal_nextHot() {
		return !this.hotList.isEmpty();
	}
	
	@Nullable ToolRunnable internal_pollHot() {
		return this.hotList.pollFirst();
	}
	
	/**
	 * Not necessary in synchronized block
	 */
	void internal_onFinished(final ToolRunnable runnable, final int detail) {
		assert (runnable == this.finishedExpected.peek().get(0));
		
		addContentChangeEvent(new TaskDelta(detail, -1, this.finishedExpected.poll()));
	}
	
	private int internal_getCompleteSize() {
		int size= 0;
		for (int iSection= this.sectionStack.size() - 1; iSection >= 0; iSection--) {
			size+= this.sectionStack.get(iSection).getAllSize();
		}
		return size;
	}
	
	private int internal_getSize(final int startSection, final int endSection) {
		int size= 0;
		for (int iSection= endSection - 1; iSection >= startSection; iSection--) {
			size+= this.sectionStack.get(iSection).getAllSize();
		}
		return size;
	}
	
	private ImList<ToolRunnable> internal_createCompleteList() {
		final ToolRunnable[] runnables= new @NonNull ToolRunnable[
				internal_getCompleteSize() ];
		int i= 0;
		for (int iSection= this.sectionStack.size() - 1; iSection >= 0; iSection--) {
			i= this.sectionStack.get(iSection).getAll(runnables, i);
		}
		return ImCollections.newList(runnables);
	}
	
	List<ToolRunnable> internal_getList() {
		internal_check();
		return internal_createCompleteList();
	}
	
	List<ToolRunnable> internal_getCurrentList() {
		internal_check();
		return this.currentSection.list;
	}
	
	
	public synchronized boolean isRequested(final byte state) {
		return (this.state == state || this.stateRequest == state);
	}
	
	public synchronized boolean pause() {
		if (this.state == TERMINATED_STATE) {
			return false;
		}
		final byte oldState= this.stateRequest;
		if (oldState != PAUSED_STATE) {
			this.stateRequest= PAUSED_STATE;
			addStateEvent(DebugEvent.MODEL_SPECIFIC, STATE_REQUEST,
					new StateDelta(oldState, PAUSED_STATE));
			internal_fireEvents();
			notifyAll();
		}
		return true;
	}
	
	public synchronized boolean resume() {
		if (this.state == TERMINATED_STATE) {
			return false;
		}
		final byte oldState= this.stateRequest;
		if (oldState != PROCESSING_STATE) {
			this.stateRequest= PROCESSING_STATE;
			addStateEvent(DebugEvent.MODEL_SPECIFIC, STATE_REQUEST,
					new StateDelta(oldState, PROCESSING_STATE) );
			internal_fireEvents();
			notifyAll();
		}
		return true;
	}
	
	void internal_onStatusChanged(final ToolStatus newStatus) {
		final byte oldState= this.state;
		switch (newStatus) {
		case STARTED_IDLING:
		case STARTED_SUSPENDED:
			this.state= IDLING_STATE;
			break;
		case STARTED_PAUSED:
			this.state= PAUSED_STATE;
			break;
		case TERMINATED:
			this.state= TERMINATED_STATE;
			break;
		default:
			this.state= PROCESSING_STATE;
			break;
		}
		
		addStateEvent(DebugEvent.CHANGE, DebugEvent.STATE,
				new StateDelta(oldState, this.state) );
		
		if (this.stateRequest == PAUSED_STATE && oldState == PAUSED_STATE) {
			this.stateRequest= PROCESSING_STATE;
			addStateEvent(DebugEvent.MODEL_SPECIFIC, STATE_REQUEST,
					new StateDelta(PAUSED_STATE, PROCESSING_STATE) );
		}
		else if (this.stateRequest == TERMINATED_STATE && this.state == TERMINATED_STATE) {
			this.stateRequest= PROCESSING_STATE;
			addStateEvent(DebugEvent.MODEL_SPECIFIC, STATE_REQUEST,
					new StateDelta(TERMINATED_STATE, PROCESSING_STATE) );
		}
	}
	
	boolean internal_isPauseRequested() {
		return (this.stateRequest == PAUSED_STATE);
	}
	
	
	void internal_dispose() {
		checkIOCache();
		
		final byte oldState= this.state;
		if (oldState != TERMINATED_STATE) {
			this.state= TERMINATED_STATE;
			addStateEvent(DebugEvent.CHANGE, DebugEvent.STATE,
					new StateDelta(oldState, TERMINATED_STATE) );
		}
		
		final ImList<ToolRunnable> finalRunnables;
		{	final ToolRunnable[] runnables= new @NonNull ToolRunnable[
					internal_getCompleteSize() ];
			int i= 0;
			for (int iSection= this.sectionStack.size() - 1; iSection >= 1; iSection--) {
				final SubQueue removedSection= this.sectionStack.remove(iSection);
				i= removedSection.getAll(runnables, i);
				removedSection.dispose();
			}
			{	// iSection == 0
				i= this.topLevelSection.getAll(runnables, i);
				this.topLevelSection.dispose();
			}
			this.currentSection= this.topLevelSection;
			this.currentSection.next= null;
			
			finalRunnables= ImCollections.newList(runnables);
		}
		for (final ToolRunnable runnable : finalRunnables) {
			runnable.changed(ToolRunnable.BEING_ABANDONED, this.process);
		}
		addTerminateEvent(new TaskDelta(ToolRunnable.BEING_ABANDONED, -1, finalRunnables));
		
		if (!this.hotList.isEmpty()){
			final ImList<ToolRunnable> leftRunnable= ImCollections.toList(this.hotList);
			this.hotList.clear();
			
			for (final ToolRunnable runnable : leftRunnable) {
				runnable.changed(ToolRunnable.BEING_ABANDONED, this.process);
			}
		}
		if (!this.onIdleList.isEmpty()){
			final ImList<RankedItem> leftRunnable= ImCollections.toList(this.onIdleList);
			this.onIdleList.clear();
			
			for (final RankedItem item : leftRunnable) {
				item.runnable.changed(ToolRunnable.BEING_ABANDONED, this.process);
			}
		}
		
		internal_fireEvents();
	}
	
	
	private void checkIOCache() {
		if (this.singleIOCache != null) {
			final int idx= this.currentSection.getAppendIdx();
			this.currentSection.append(this.singleIOCache.get(0));
			addContentChangeEvent(new TaskDelta(ToolRunnable.ADDING_TO, idx, this.singleIOCache));
			this.singleIOCache= null;
		}
	}
	
	
	private void addContentChangeEvent(final TaskDelta delta) {
		final DebugEvent event= new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CONTENT);
		event.setData(delta);
		this.eventList.add(event);
	}
	
	private void addStateEvent(final int kind, final int detail, final StateDelta delta) {
		final DebugEvent event= new DebugEvent(this, kind, detail);
		event.setData(delta);
		this.eventList.add(event);
	}
	
	private void addTerminateEvent(final TaskDelta delta) {
		final DebugEvent event= new DebugEvent(this, DebugEvent.TERMINATE, DebugEvent.UNSPECIFIED);
		event.setData(delta);
		this.eventList.add(event);
	}
	
	List<DebugEvent> internal_getEventList() {
		return this.eventList;
	}
	
	void internal_fireEvents() {
		if (this.eventList.isEmpty()) {
			return;
		}
		final DebugPlugin manager= DebugPlugin.getDefault();
		if (manager != null) {
			manager.fireDebugEventSet(this.eventList.toArray(new DebugEvent[this.eventList.size()]));
		}
		this.eventList.clear();
	}
	
}
