/*******************************************************************************
 * Copyright (c) 2014 Google Inc and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Thirumala Reddy Mutchukota - initial API and implementation
 *******************************************************************************/

package org.eclipse.core.runtime.jobs;

import java.util.List;
import org.eclipse.core.internal.jobs.InternalJobGroup;
import org.eclipse.core.runtime.*;

/**
 * JobGroups support throttling, join, cancel, combined progress and error reporting
 * on a group of jobs.
 * <ul>
 * <li>A JobGroup object represents a group of Jobs. Any number of jobs
 * can be added to a group, but a Job can be part of only one group at a time.
 * <li>A JobGroup can be configured with a throttling number, so that only that many
 * jobs from the group are allowed to run in parallel.
 * <li>One can join on all of the jobs in the group and observe the completion progress
 * of those jobs.
 * <li>One can cancel all the jobs in the group.
 * <li>A JobGroup consolidates the return statuses of all the jobs in the group
 * and a single MultiStatus message is available after all the jobs in the group
 * are completed.
 * </ul>
 * <p>
 * JobGroups maintain state for the collective status of the jobs belonging to the group.
 * When constructed, a job group starts with a state value of <code>NONE</code>.
 * When any job belonging to the group is scheduled to run, the job group moves into the
 * <code>ACTIVE</code> state. A job group enters the <code>CANCELING</code> state
 * when cancellation of the whole group is requested. The group will be in this state
 * until all the jobs in the group have finished either through cancellation or
 * normal completion. When a job group is in the <code>CANCELING</code> state,
 * newly scheduled jobs which are part of that group are immediately canceled.
 * When execution of all the jobs belonging to a job group finishes (either normally
 * or through cancellation), the job group state changes back to <code>NONE</code>.
 *
 * @see IJobManager
 * @since 3.7
 */
public class JobGroup extends InternalJobGroup {
	/**
	 * JobGroup state code (value 0) indicating that none of the jobs belonging to
	 * the group are running or scheduled to run.
	 *
	 * @see #getState()
	 */
	public static final int NONE = 0;
	/**
	 * JobGroup state code (value 1) indicating that at least one job belonging to
	 * the group is running or scheduled to run.
	 *
	 * @see #getState()
	 */
	public static final int ACTIVE = 0x01;
	/**
	 * JobGroup state code (value 2) indicating that cancellation of the whole group is requested.
	 * The group will be in this state until all the jobs in the group have finished either through
	 * cancellation or normal completion. When a job group is in this state, newly scheduled jobs
	 * which are part of that group are immediately canceled.
	 */
	public static final int CANCELING = 0x02;

	/**
	 * Creates a new job group with the specified <code>name</code> and <code>maxThreads</code>.
	 * The job group name is a human-readable value that is displayed to users.  The name does
	 * not need to be unique, but it must not be <code>null</code>. The <code>maxThreads</code>
	 * indicates the maximum number of threads allowed to be concurrently scheduled by the
	 * jobs belonging to the group at any given time, or <code>zero</code> to indicate that
	 * no throttling should be applied and all jobs should be allowed to run as soon as possible.
	 *
	 * @param name the name of the job group.
	 * @param maxThreads the maximum number of threads allowed to be concurrently scheduled,
	 * or <code>zero</code> to indicate that no throttling should be applied and all jobs
	 * should be allowed to run as soon as possible.
	 * @param seedJobsCount the initial number of jobs that will be added to the job group.
	 * This is the initial count of jobs with which the creator of the job group will "seed"
	 * the job group. Those initial jobs may discover more work and add yet more jobs, but
	 * those additional jobs should not be included in this initial "seed" count. If this
	 * value is set too high, the job group will never transition to the done ({@link #NONE})
	 * state, {@link #join(long, IProgressMonitor)} calls will hang, and {@link #getResult()}
	 * calls will return invalid results. If this value is set too low, the job group may
	 * transition to the ({@link #NONE}) state before all of the jobs have been scheduled,
	 * causing a {@link #join(long, IProgressMonitor)} call to return too early.
	 */
	public JobGroup(String name, int maxThreads, int seedJobsCount) {
		super(name, maxThreads, seedJobsCount);
	}

	/**
	 * Returns the human readable name of this job group.  The name is never <code>null</code>.
	 *
	 * @return the name of this job group
	 */
	@Override
	public final String getName() {
		return super.getName();
	}

	/**
	 * Returns the maximum number of threads allowed to be scheduled by the jobs belonging
	 * to the group at any given time, or <code>zero</code> to indicate that no throttling
	 * should be applied and all jobs should be allowed to run as soon as possible.
	 *
	 * @return the maximum number of threads allowed to be used.
	 */
	@Override
	public final int getMaxThreads() {
		return super.getMaxThreads();
	}

	/**
	 * Returns the result of this job group's last run. If a job group completes and then
	 * its jobs are rescheduled, this method returns the results of the previous run.
	 *
	 * @return the result of this job group's last run, or <code>null</code> if this
	 * job group has never finished running.
	 */
	@Override
	public final MultiStatus getResult() {
		return super.getResult();
	}

	/**
	 * Returns the state of the job group. Result will be one of:
	 * <ul>
	 * <li><code>JobGroup.NONE</code> - when the jobs belonging to the group are not yet scheduled to run.</li>
	 * <li><code>JobGroup.ACTIVE</code> - when the jobs belonging to the group are running or scheduled to run.</li>
	 * <li><code>JobGroup.CANCELING</code> - when the jobs belonging to the group are being canceled.</li>
	 * </ul>
	 * <p>
	 * Note that job group state is inherently volatile, and in most cases clients cannot rely
	 * on the result of this method being valid by the time the result is obtained. For example,
	 * if <tt>getState</tt> returns <tt>ACTIVE</tt>, the job group may have actually completed
	 * by the time the <tt>getState</tt> method returns. All that clients can infer from invoking
	 * this method is that the job group was recently in the returned state.
	 *
	 * @return the job group state
	 */
	@Override
	public final int getState() {
		return super.getState();
	}

	/**
	 * Returns all waiting, executing and sleeping jobs belonging
	 * to this job group. If no jobs are found, an empty array is returned.
	 *
	 * @return the list of active jobs
	 * @see Job#setJobGroup(JobGroup)
	 */
	@Override
	public final List<Job> getActiveJobs() {
		return super.getActiveJobs();
	}

	/**
	 * Cancels all jobs belonging to this job group. Jobs belonging to this group
	 * that are currently in the <code>WAITING</code> state will be removed from the queue.
	 * Sleeping jobs will be discarded without having a chance to wake up.
	 * Currently executing jobs will be asked to cancel but there is no guarantee
	 * that they will do so.
	 * <p>
	 * The job group will be placed into <code>CANCELING</code> state and will be
	 * in that state until all the jobs in the group have finished either through
	 * cancellation or normal completion. When a job group is in the <code>CANCELING</code>
	 * state, newly scheduled jobs which are part of the group are immediately canceled.
	 *
	 * @see Job#setJobGroup(JobGroup)
	 * @see JobGroup#getState()
	 */
	@Override
	public final void cancel() {
		super.cancel();
	}

	/**
	 * Waits until either all jobs belonging to this job group have finished or
	 * the given timeout has expired. This method will block the calling thread
	 * until all such jobs have finished executing, or the given timeout is
	 * expired, or the given progress monitor is canceled by the user or the
	 * calling thread is interrupted. If there are no jobs belonging to the
	 * group that are currently waiting, running, or sleeping, this method
	 * returns immediately. Feedback on how the join is progressing is provided
	 * to the given progress monitor.
	 * <p>
	 * If this method is called while the job manager is suspended, only jobs
	 * that are currently running will be joined. Once there are no jobs belongs
	 * to the group in the {@link Job#RUNNING} state, the method returns.
	 * </p>
	 * <p>
	 * Jobs may be added to this job group after the initial set of jobs are
	 * scheduled, and this method will wait for all newly added jobs to complete
	 * (or the given timeout has expired), even if they are added to the group
	 * after this method is invoked.
	 * </p>
	 * <p>
	 * Throws an <code>OperationCanceledException</code> when the given progress
	 * monitor is canceled. Canceling the monitor does not cancel the jobs
	 * belonging to the group and, if required, the group may be canceled
	 * explicitly using the {@link #cancel()} method.
	 * </p>
	 * <p>
	 * <b>NOTE:</b> If the job manager is suspended, the result of the job group
	 * run may not be set when this method returns.
	 * </p>
	 *
	 * @param timeoutMillis
	 *            the maximum amount of time to wait for the join to complete,
	 *            or <code>zero</code> for no timeout.
	 * @param monitor
	 *            the progress monitor for reporting progress on how the wait is
	 *            progressing and to be able to cancel the join operation, or
	 *            <code>null</code> if no progress monitoring is required.
	 * @return <code>true</code> when all the jobs in the group complete, or
	 *         <code>false</code> when the operation is not completed within the
	 *         given time.
	 * @exception InterruptedException
	 *                if the calling thread is interrupted while waiting
	 * @exception OperationCanceledException
	 *                if the progress monitor is canceled while waiting
	 * @see Job#setJobGroup(JobGroup)
	 * @see #cancel()
	 */
	@Override
	public final boolean join(long timeoutMillis, IProgressMonitor monitor) throws InterruptedException, OperationCanceledException {
		return super.join(timeoutMillis, monitor);
	}

	/**
	 * This method is called by the JobManager after the completion of every job belonging
	 * to this group, and is used to control the job group's cancellation policy. Returning
	 * <code>true</code> from this function causes all remaining running and scheduled jobs
	 * to be canceled.
	 * <p>
	 * The default implementation returns <code>true</code> when <code>numberOfFailedJobs &gt; 0</code>.
	 * Subclasses may override this method to implement a different cancellation strategy.
	 *
	 * @param lastCompletedJobResult result of the last completed job belonging to this group.
	 * @param numberOfFailedJobs the total number of jobs belonging to this group that are
	 *     finished with status <code>IStatus.ERROR</code>.
	 * @param numberOfCanceledJobs the total number of jobs belonging to this group that are
	 *     finished with status <code>IStatus.CANCEL</code>.
	 * @return <code>true</code> when the remaining jobs belonging to this group should be canceled.
	 */
	@Override
	protected boolean shouldCancel(IStatus lastCompletedJobResult, int numberOfFailedJobs, int numberOfCanceledJobs) {
		return super.shouldCancel(lastCompletedJobResult, numberOfFailedJobs, numberOfCanceledJobs);
	}

	/**
	 * This method is called by the JobManager when all the jobs belonging to the group
	 * are completed. The combined status returned by this method is used as the result
	 * of the job group.
	 * <p>
	 * The default implementation will return a <code>MultiStatus</code> object containing
	 * the returned statuses of the completed jobs. The results with <code>IStatus.OK</code>
	 * are omitted from the result since those statuses usually do not contain valuable information.
	 * Subclasses may override this method to implement custom status reporting,
	 * but should never return <code>null</code>.
	 *
	 * @param jobResults results of all the completed jobs belonging to this group.
	 * @return the combined status of the group, not <code>null</code>.
	 * @see #getResult()
	 */
	@Override
	protected MultiStatus computeGroupResult(List<IStatus> jobResults) {
		return super.computeGroupResult(jobResults);
	}
}
