/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ui.synchronize;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.*;
import org.eclipse.team.core.mapping.IResourceDiffTree;
import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
import org.eclipse.team.core.synchronize.*;
import org.eclipse.team.internal.core.subscribers.*;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.ui.synchronize.*;

/**
 * Group incoming changes according to the active change set that are
 * located in
 */
public class ActiveChangeSetCollector implements IDiffChangeListener {

    private final ISynchronizePageConfiguration configuration;

    /*
     * Map active change sets to infos displayed by the participant
     */
    private final Map<ChangeSet, SyncInfoSet> activeSets = new HashMap<>();

    /*
     * Set which contains those changes that are not part of an active set
     */
    private SyncInfoTree rootSet = new SyncInfoTree();

    private final ChangeSetModelProvider provider;

    /*
     * Listener registered with active change set manager
     */
    private IChangeSetChangeListener activeChangeSetListener = new IChangeSetChangeListener() {

        @Override
		public void setAdded(final ChangeSet set) {
            // Remove any resources that are in the new set
            provider.performUpdate(monitor -> {
			    remove(set.getResources());
			    createSyncInfoSet(set);
			}, true, true);
        }

        @Override
		public void defaultSetChanged(final ChangeSet previousDefault, final ChangeSet set) {
            provider.performUpdate(monitor -> {
			    if (listener != null)
			        listener.defaultSetChanged(previousDefault, set);
			}, true, true);
        }

        @Override
		public void setRemoved(final ChangeSet set) {
            provider.performUpdate(monitor -> {
			    remove(set);
			    if (!set.isEmpty()) {
			        add(getSyncInfos(set).getSyncInfos());
			    }
			}, true, true);
        }

        @Override
		public void nameChanged(final ChangeSet set) {
            provider.performUpdate(monitor -> {
			    if (listener != null)
			        listener.nameChanged(set);
			}, true, true);
        }

        @Override
		public void resourcesChanged(final ChangeSet set, final IPath[] paths) {
            // Look for any resources that were removed from the set but are still out-of sync.
            // Re-add those resources
            final List<SyncInfo> outOfSync = new ArrayList<>();
            for (int i = 0; i < paths.length; i++) {
				IPath path = paths[i];
                if (!((DiffChangeSet)set).contains(path)) {
                    SyncInfo info = getSyncInfo(path);
                    if (info != null && info.getKind() != SyncInfo.IN_SYNC) {
                        outOfSync.add(info);
                    }
                }
            }
            if (!outOfSync.isEmpty()) {
                provider.performUpdate(monitor -> add(outOfSync.toArray(new SyncInfo[outOfSync.size()])), true, true);
            }
        }
    };

    /**
     * Listener that wants to receive change events from this collector
     */
    private IChangeSetChangeListener listener;

    public ActiveChangeSetCollector(ISynchronizePageConfiguration configuration, ChangeSetModelProvider provider) {
        this.configuration = configuration;
        this.provider = provider;
        getActiveChangeSetManager().addListener(activeChangeSetListener);
    }

    public ISynchronizePageConfiguration getConfiguration() {
        return configuration;
    }

    public ActiveChangeSetManager getActiveChangeSetManager() {
        ISynchronizeParticipant participant = getConfiguration().getParticipant();
        if (participant instanceof IChangeSetProvider) {
            return ((IChangeSetProvider)participant).getChangeSetCapability().getActiveChangeSetManager();
        }
        return null;
    }

    /**
     * Re-populate the change sets from the seed set.
     * If <code>null</code> is passed, the state
     * of the collector is cleared but the set is not
     * re-populated.
     * <p>
     * This method is invoked by the model provider when the
     * model provider changes state. It should not
     * be invoked by other clients. The model provider
     * will invoke this method from a particular thread (which may
     * or may not be the UI thread). Updates done to the collector
     * from within this thread will be thread-safe and update the view
     * properly. Updates done from other threads should use the
     * <code>performUpdate</code> method to ensure the view is
     * updated properly.
     * @param seedSet
     */
    public void reset(SyncInfoSet seedSet) {
        // First, clean up
        rootSet.clear();
        ChangeSet[] sets = activeSets.keySet().toArray(new ChangeSet[activeSets.size()]);
        for (int i = 0; i < sets.length; i++) {
            ChangeSet set = sets[i];
            remove(set);
        }
        activeSets.clear();

        // Now re-populate
        if (seedSet != null) {
            if (getConfiguration().getComparisonType() == ISynchronizePageConfiguration.THREE_WAY) {
	            // Show all active change sets even if they are empty
	            sets = getActiveChangeSetManager().getSets();
	            for (int i = 0; i < sets.length; i++) {
	                ChangeSet set = sets[i];
	                add(set);
	            }
	            // The above will add all sync info that are contained in sets.
	            // We still need to add uncontained infos to the root set
	            SyncInfo[] syncInfos = seedSet.getSyncInfos();
	            for (int i = 0; i < syncInfos.length; i++) {
	                SyncInfo info = syncInfos[i];
	                if (isLocalChange(info)) {
	                    ChangeSet[] containingSets = findChangeSets(info);
	                    if (containingSets.length == 0) {
	                        rootSet.add(info);
	                    }
	                }
	            }
            } else {
                add(seedSet.getSyncInfos());
            }
        }
    }

    /**
     * Handle a sync info set change event from the provider's
     * seed set.
     * <p>
     * This method is invoked by the model provider when the
     * model provider changes state. It should not
     * be invoked by other clients. The model provider
     * will invoke this method from a particular thread (which may
     * or may not be the UI thread). Updates done to the collector
     * from within this thread will be thread-safe and update the view
     * properly. Updates done from other threads should use the
     * <code>performUpdate</code> method to ensure the view is
     * updated properly.
     */
    public void handleChange(ISyncInfoSetChangeEvent event) {
        List<IResource> removals = new ArrayList<>();
        List<SyncInfo> additions = new ArrayList<>();
        removals.addAll(Arrays.asList(event.getRemovedResources()));
        additions.addAll(Arrays.asList(event.getAddedResources()));
        SyncInfo[] changed = event.getChangedResources();
        for (int i = 0; i < changed.length; i++) {
            SyncInfo info = changed[i];
            additions.add(info);
            removals.add(info.getLocal());
        }
        if (!removals.isEmpty()) {
            remove(removals.toArray(new IResource[removals.size()]));
        }
        if (!additions.isEmpty()) {
            add(additions.toArray(new SyncInfo[additions.size()]));
        }
    }

    /**
     * Remove the given resources from all sets of this collector.
     * @param resources the resources to be removed
     */
    protected void remove(IResource[] resources) {
        for (Iterator iter = activeSets.values().iterator(); iter.hasNext();) {
            SyncInfoSet set = (SyncInfoSet) iter.next();
            set.removeAll(resources);
        }
        rootSet.removeAll(resources);
    }

    protected void add(SyncInfo[] infos) {
    	rootSet.beginInput();
        for (int i = 0; i < infos.length; i++) {
            SyncInfo info = infos[i];
            if (isLocalChange(info) && select(info)) {
                ChangeSet[] sets = findChangeSets(info);
                if (sets.length == 0) {
                    rootSet.add(info);
                } else {
	                for (int j = 0; j < sets.length; j++) {
	                    ChangeSet set = sets[j];
	                    SyncInfoSet targetSet = getSyncInfoSet(set);
	                    if (targetSet == null) {
	                        // This will add all the appropriate sync info to the set
	                        createSyncInfoSet(set);
	                    } else {
	                        targetSet.add(info);
	                    }
	                }
                }
            }
        }
        rootSet.endInput(null);
    }

    private ChangeSet[] findChangeSets(SyncInfo info) {
        ActiveChangeSetManager manager = getActiveChangeSetManager();
        ChangeSet[] sets = manager.getSets();
        List<ChangeSet> result = new ArrayList<>();
        for (int i = 0; i < sets.length; i++) {
            ChangeSet set = sets[i];
            if (set.contains(info.getLocal())) {
                result.add(set);
            }
        }
        return result.toArray(new ChangeSet[result.size()]);
    }

    /*
	 * Return if this sync info is an outgoing change.
	 */
	private boolean isLocalChange(SyncInfo info) {
	    if (!info.getComparator().isThreeWay()) {
	        try {
                // Obtain the sync info from the subscriber and use it to see if the change is local
                info = ((SubscriberChangeSetManager)getActiveChangeSetManager()).getSubscriber().getSyncInfo(info.getLocal());
            } catch (TeamException e) {
                TeamUIPlugin.log(e);
            }
	    }
		return (info.getComparator().isThreeWay()
		        && ((info.getKind() & SyncInfo.DIRECTION_MASK) == SyncInfo.OUTGOING ||
		                (info.getKind() & SyncInfo.DIRECTION_MASK) == SyncInfo.CONFLICTING));
	}

    public SyncInfoTree getRootSet() {
        return rootSet;
    }

    /*
     * Add the set from the collector.
     */
    public void add(ChangeSet set) {
        SyncInfoSet targetSet = getSyncInfoSet(set);
        if (targetSet == null) {
            createSyncInfoSet(set);
        }
        if (listener != null) {
            listener.setAdded(set);
        }
    }

    private SyncInfoTree createSyncInfoSet(ChangeSet set) {
        SyncInfoTree sis = getSyncInfoSet(set);
        // Register the listener last since the add will
        // look for new elements
        boolean added = false;
        // Use a variable to ensure that both begin and end are invoked
        try {
	        if (sis == null) {
	            sis = new SyncInfoTree();
	            activeSets.put(set, sis);
	            added = true;
	        }
            sis.beginInput();
            if (!sis.isEmpty())
                sis.removeAll(sis.getResources());
            sis.addAll(getSyncInfos(set));
        } finally {
            if (sis != null)
                sis.endInput(null);
        }
        if (added) {
            ((DiffChangeSet)set).getDiffTree().addDiffChangeListener(this);
            if (listener != null)
                listener.setAdded(set);
        }
        return sis;
    }

	private SyncInfoSet getSyncInfos(ChangeSet set) {
		IDiff[] diffs = ((ResourceDiffTree)((DiffChangeSet)set).getDiffTree()).getDiffs();
		return asSyncInfoSet(diffs);
	}

	private SyncInfoSet asSyncInfoSet(IDiff[] diffs) {
		SyncInfoSet result = new SyncInfoSet();
		for (int i = 0; i < diffs.length; i++) {
			IDiff diff = diffs[i];
			if (select(diff)) {
				SyncInfo info = asSyncInfo(diff);
				if (info != null)
					result.add(info);
			}
		}
		return result;
	}

    private SyncInfo asSyncInfo(IDiff diff) {
		try {
			return ((SubscriberParticipant)getConfiguration().getParticipant()).getSubscriber().getSyncInfo(ResourceDiffTree.getResourceFor(diff));
		} catch (TeamException e) {
			TeamUIPlugin.log(e);
		}
		return null;
	}

	private boolean select(IDiff diff) {
    	return getSeedSet().getSyncInfo(ResourceDiffTree.getResourceFor(diff)) != null;
	}

	/* private */ SyncInfo getSyncInfo(IPath path) {
		return getSyncInfo(getSeedSet(), path);
	}

	/* private */ IResource[] getResources(SyncInfoSet set, IPath[] paths) {
		List<IResource> result = new ArrayList<>();
		for (int i = 0; i < paths.length; i++) {
			IPath path = paths[i];
			SyncInfo info = getSyncInfo(set, path);
			if (info != null) {
				result.add(info.getLocal());
			}
		}
		return result.toArray(new IResource[result.size()]);
	}

	private SyncInfo getSyncInfo(SyncInfoSet set, IPath path) {
		SyncInfo[] infos = set.getSyncInfos();
		for (int i = 0; i < infos.length; i++) {
			SyncInfo info = infos[i];
			if (info.getLocal().getFullPath().equals(path))
				return info;
		}
		return null;
	}

	/*
     * Remove the set from the collector.
     */
    public void remove(ChangeSet set) {
    	((DiffChangeSet)set).getDiffTree().removeDiffChangeListener(this);
        activeSets.remove(set);
        if (listener != null) {
            listener.setRemoved(set);
        }
    }

    /*
     * Return the sync info set for the given active change set
     * or null if there isn't one.
     */
    public SyncInfoTree getSyncInfoSet(ChangeSet set) {
        return (SyncInfoTree)activeSets.get(set);
    }

    private ChangeSet getChangeSet(IDiffTree tree) {
        for (Iterator iter = activeSets.keySet().iterator(); iter.hasNext();) {
            ChangeSet changeSet = (ChangeSet) iter.next();
            if (((DiffChangeSet)changeSet).getDiffTree() == tree) {
                return changeSet;
            }
        }
        return null;
    }

    private boolean select(SyncInfo info) {
        return getSeedSet().getSyncInfo(info.getLocal()) != null;
    }

    private SyncInfoSet getSeedSet() {
        return provider.getSyncInfoSet();
    }

    public void dispose() {
        getActiveChangeSetManager().removeListener(activeChangeSetListener);
    }

    /**
     * Set the change set listener for this collector. There is
     * only one for this type of collector.
     * @param listener change set change listener
     */
    public void setChangeSetChangeListener(IChangeSetChangeListener listener) {
        this.listener = listener;
        if (listener == null) {
            getActiveChangeSetManager().removeListener(activeChangeSetListener);
        } else {
            getActiveChangeSetManager().addListener(activeChangeSetListener);
        }
    }

	@Override
	public void diffsChanged(final IDiffChangeEvent event, IProgressMonitor monitor) {
        provider.performUpdate(monitor1 -> {
		    ChangeSet changeSet = getChangeSet(event.getTree());
		    if (changeSet != null) {
		        SyncInfoSet targetSet = getSyncInfoSet(changeSet);
		        if (targetSet != null) {
		            targetSet.removeAll(getResources(targetSet, event.getRemovals()));
		            targetSet.addAll(asSyncInfoSet(event.getAdditions()));
		            targetSet.addAll(asSyncInfoSet(event.getChanges()));
		            rootSet.removeAll(((IResourceDiffTree)event.getTree()).getAffectedResources());
		        }
		    }
		}, true /* preserver expansion */, true /* run in UI thread */);
	}

	@Override
	public void propertyChanged(IDiffTree tree, int property, IPath[] paths) {
		// Nothing to do
	}
}
