/*******************************************************************************
 * Copyright (c) 2003, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.progress;

import java.time.Duration;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import org.eclipse.jface.util.Throttler;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.util.PrefUtil;

/**
 * The ProgressViewUpdater is the singleton that updates viewers.
 */
class ProgressViewUpdater implements IJobProgressManagerListener {

    private static ProgressViewUpdater singleton;

    private IProgressUpdateCollector[] collectors;

    UpdatesInfo currentInfo = new UpdatesInfo();

    boolean debug;

	Throttler throttledUpdate = new Throttler(PlatformUI.getWorkbench().getDisplay(), Duration.ofMillis(100),
			this::update);

    /**
     * The UpdatesInfo is a private class for keeping track of the updates
     * required.
     */
	static class UpdatesInfo {

		Collection<JobTreeElement> additions = new LinkedHashSet<>();

		Collection<JobTreeElement> deletions = new LinkedHashSet<>();

		Collection<JobTreeElement> refreshes = new LinkedHashSet<>();

		boolean updateAll;

        private UpdatesInfo() {
            //Create a new instance of the info
        }

        /**
         * Add an add update
         *
         * @param addition
         */
		void add(JobTreeElement addition) {
            additions.add(addition);
        }

        /**
         * Add a remove update
         *
         * @param removal
         */
		void remove(JobTreeElement removal) {
            deletions.add(removal);
        }

        /**
         * Add a refresh update
         *
         * @param refresh
         */
		void refresh(JobTreeElement refresh) {
            refreshes.add(refresh);
        }

        /**
         * Reset the caches after completion of an update.
         */
		void reset() {
            additions.clear();
            deletions.clear();
            refreshes.clear();
            updateAll = false;
        }

		void processForUpdate() {
			HashSet<JobTreeElement> staleAdditions = new HashSet<>();

            Iterator<JobTreeElement> additionsIterator = additions.iterator();
            while (additionsIterator.hasNext()) {
                JobTreeElement treeElement = additionsIterator
                        .next();
                if (!treeElement.isActive()) {
                    if (deletions.contains(treeElement)) {
						staleAdditions.add(treeElement);
					}
                }
            }

            additions.removeAll(staleAdditions);

			HashSet<JobTreeElement> obsoleteRefresh = new HashSet<>();
            Iterator<JobTreeElement> refreshIterator = refreshes.iterator();
            while (refreshIterator.hasNext()) {
                JobTreeElement treeElement = refreshIterator
                        .next();
                if (deletions.contains(treeElement)
                        || additions.contains(treeElement)) {
					obsoleteRefresh.add(treeElement);
				}

                //Also check for groups that are being added
               Object parent = treeElement.getParent();
               if(parent != null && (deletions.contains(parent)
                       || additions.contains(parent))){
            	   obsoleteRefresh.add(treeElement);
               }

                if (!treeElement.isActive()) {
                    //If it is done then delete it
                    obsoleteRefresh.add(treeElement);
                    deletions.add(treeElement);
                }
            }

            refreshes.removeAll(obsoleteRefresh);

        }
    }

    /**
     * Return a new instance of the receiver.
     *
     * @return ProgressViewUpdater
     */
   static ProgressViewUpdater getSingleton() {
        if (singleton == null) {
			singleton = new ProgressViewUpdater();
		}
        return singleton;
    }

    /**
     * Return whether or not there is a singleton for updates to avoid creating
     * extra listeners.
     *
     * @return boolean <code>true</code> if there is already
     * a singleton
     */
    static boolean hasSingleton() {
        return singleton != null;
    }

    static void clearSingleton() {
        if (singleton != null) {
			ProgressManager.getInstance().removeListener(singleton);
		}
        singleton = null;
    }

    /**
     * Create a new instance of the receiver.
     */
    private ProgressViewUpdater() {
        collectors = new IProgressUpdateCollector[0];
        ProgressManager.getInstance().addListener(this);
        debug =
        	PrefUtil.getAPIPreferenceStore().
        		getBoolean(IWorkbenchPreferenceConstants.SHOW_SYSTEM_JOBS);
    }

    /**
     * Add the new collector to the list of collectors.
     *
     * @param newCollector
     */
    void addCollector(IProgressUpdateCollector newCollector) {
        IProgressUpdateCollector[] newCollectors = new IProgressUpdateCollector[collectors.length + 1];
        System.arraycopy(collectors, 0, newCollectors, 0, collectors.length);
        newCollectors[collectors.length] = newCollector;
        collectors = newCollectors;
    }

    /**
     * Remove the collector from the list of collectors.
     *
     * @param provider
     */
    void removeCollector(IProgressUpdateCollector provider) {
		HashSet<IProgressUpdateCollector> newCollectors = new HashSet<>();
        for (int i = 0; i < collectors.length; i++) {
            if (!collectors[i].equals(provider)) {
				newCollectors.add(collectors[i]);
			}
        }
        IProgressUpdateCollector[] newArray = new IProgressUpdateCollector[newCollectors
                .size()];
        newCollectors.toArray(newArray);
        collectors = newArray;
        //Remove ourselves if there is nothing to update
        if (collectors.length == 0) {
			clearSingleton();
		}
    }

	private void update() {
		// Abort the update if there isn't anything
		if (collectors.length == 0) {
			return;
		}

		if (currentInfo.updateAll) {
			currentInfo.reset();
			for (IProgressUpdateCollector collector : collectors) {
				collector.refresh();
			}

		} else {
			// Lock while getting local copies of the caches.
			JobTreeElement[] updateItems;
			JobTreeElement[] additionItems;
			JobTreeElement[] deletionItems;

			currentInfo.processForUpdate();

			updateItems = currentInfo.refreshes.toArray(new JobTreeElement[0]);
			additionItems = currentInfo.additions.toArray(new JobTreeElement[0]);
			deletionItems = currentInfo.deletions.toArray(new JobTreeElement[0]);

			currentInfo.reset();

			for (IProgressUpdateCollector collector : collectors) {
				if (updateItems.length > 0) {
					collector.refresh(updateItems);
				}
				if (additionItems.length > 0) {
					collector.add(additionItems);
				}
				if (deletionItems.length > 0) {
					collector.remove(deletionItems);
				}
			}
		}
	}

    /**
     * Refresh the supplied JobInfo.
     * @param info
     */
    public void refresh(JobInfo info) {
		currentInfo.refresh(info);
		GroupInfo group = info.getGroupInfo();
		if (group != null) {
			currentInfo.refresh(group);
		}
        //Add in a 100ms delay so as to keep priority low
		throttledUpdate.throttledExec();

    }

    @Override
	public void refreshJobInfo(JobInfo info) {
		currentInfo.refresh(info);
        //Add in a 100ms delay so as to keep priority low
		throttledUpdate.throttledExec();

    }

    @Override
	public void refreshGroup(GroupInfo info) {
		currentInfo.refresh(info);
        //Add in a 100ms delay so as to keep priority low
		throttledUpdate.throttledExec();
    }

    @Override
	public void addGroup(GroupInfo info) {
		currentInfo.add(info);
		throttledUpdate.throttledExec();
    }

    @Override
	public void refreshAll() {
		currentInfo.updateAll = true;

        //Add in a 100ms delay so as to keep priority low
		throttledUpdate.throttledExec();
    }

    @Override
	public void addJob(JobInfo info) {
		GroupInfo group = info.getGroupInfo();

		if (group == null) {
			currentInfo.add(info);
		} else {
			currentInfo.refresh(group);
        }
		throttledUpdate.throttledExec();
    }

    @Override
	public void removeJob(JobInfo info) {
		GroupInfo group = info.getGroupInfo();
		if (group == null) {
			currentInfo.remove(info);
		} else {
			currentInfo.refresh(group);
        }
		throttledUpdate.throttledExec();
    }

    @Override
	public void removeGroup(GroupInfo group) {
		currentInfo.remove(group);
		throttledUpdate.throttledExec();
    }

    @Override
	public boolean showsDebug() {
        return debug;
    }

}
