/*******************************************************************************
 * Copyright (c) 2006, 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
 * Matt McCutchen <hashproduct+eclipse@gmail.com> - Bug 128429 [Change Sets] Change Sets with / in name do not get persited
 *******************************************************************************/
package org.eclipse.team.internal.core.subscribers;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.diff.IDiffChangeEvent;
import org.eclipse.team.core.diff.IDiffChangeListener;
import org.eclipse.team.core.diff.IDiffTree;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.core.mapping.IChangeGroupingRequestor;
import org.eclipse.team.core.mapping.IResourceDiffTree;
import org.eclipse.team.internal.core.Messages;
import org.eclipse.team.internal.core.TeamPlugin;
import org.eclipse.team.internal.core.mapping.CompoundResourceTraversal;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

/**
 * A change set manager that contains sets that represent collections of
 * related local changes.
 */
public abstract class ActiveChangeSetManager extends ChangeSetManager implements IDiffChangeListener, IChangeGroupingRequestor {

	private static final String CTX_DEFAULT_SET = "defaultSet"; //$NON-NLS-1$

	private ActiveChangeSet defaultSet;

	/**
	 * Return the Change Set whose sync info set is the
	 * one given.
	 * @param tree a diff tree
	 * @return the change set for the given diff tree
	 */
	protected ChangeSet getChangeSet(IResourceDiffTree tree) {
		ChangeSet[] sets = getSets();
		for (int i = 0; i < sets.length; i++) {
			ChangeSet changeSet = sets[i];
			if (((DiffChangeSet)changeSet).getDiffTree() == tree) {
				return changeSet;
			}
		}
		return null;
	}

	@Override
	public void add(ChangeSet set) {
		Assert.isTrue(set instanceof ActiveChangeSet);
		super.add(set);
	}

	@Override
	protected void handleSetAdded(ChangeSet set) {
		Assert.isTrue(set instanceof ActiveChangeSet);
		((DiffChangeSet)set).getDiffTree().addDiffChangeListener(getDiffTreeListener());
		super.handleSetAdded(set);
		handleAddedResources(set, ((ActiveChangeSet)set).internalGetDiffTree().getDiffs());
	}

	@Override
	protected void handleSetRemoved(ChangeSet set) {
		((DiffChangeSet)set).getDiffTree().removeDiffChangeListener(getDiffTreeListener());
		super.handleSetRemoved(set);
	}

	/**
	 * Return the listener that is registered with the diff trees associated with
	 * the sets for this manager.
	 * @return the listener that is registered with the diff trees associated with
	 * the sets for this manager
	 */
	protected IDiffChangeListener getDiffTreeListener() {
		return this;
	}

	@Override
	public void diffsChanged(IDiffChangeEvent event, IProgressMonitor monitor) {
		IResourceDiffTree tree = (IResourceDiffTree)event.getTree();
		handleSyncSetChange(tree, event.getAdditions(), getAllResources(event));
	}

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

	@Override
	public boolean isModified(IFile file) throws CoreException {
		IDiff diff = getDiff(file);
		if (diff != null)
			return isModified(diff);
		return false;
	}

	/**
	 * Return whether the given diff represents a local change.
	 * @param diff the diff
	 * @return whether the given diff represents a local change
	 */
	public boolean isModified(IDiff diff) {
		if (diff != null) {
			if (diff instanceof IThreeWayDiff) {
				IThreeWayDiff twd = (IThreeWayDiff) diff;
				int dir = twd.getDirection();
				return dir == IThreeWayDiff.OUTGOING || dir == IThreeWayDiff.CONFLICTING;
			} else {
				return diff.getKind() != IDiff.NO_CHANGE;
			}
		}
		return false;
	}

	/**
	 * Return the set with the given name.
	 * @param name the name of the set
	 * @return the set with the given name
	 */
	public ActiveChangeSet getSet(String name) {
		ChangeSet[] sets = getSets();
		for (int i = 0; i < sets.length; i++) {
			ChangeSet set = sets[i];
			if (set.getName().equals(name) && set instanceof ActiveChangeSet) {
				return (ActiveChangeSet)set;
			}
		}
		return null;
	}

	/**
	 * Create a change set containing the given files if
	 * they have been modified locally.
	 * @param title the title of the commit set
	 * @param files the files contained in the set
	 * @return the created set
	 * @throws CoreException
	 */
	public ActiveChangeSet createSet(String title, IFile[] files) throws CoreException {
		List<IDiff> infos = new ArrayList<>();
		for (int i = 0; i < files.length; i++) {
			IFile file = files[i];
			IDiff diff = getDiff(file);
			if (diff != null) {
				infos.add(diff);
			}
		}
		return createSet(title, infos.toArray(new IDiff[infos.size()]));
	}

	/**
	 * Create a commit set with the given title and files. The created
	 * set is not added to the control of the commit set manager
	 * so no events are fired. The set can be added using the
	 * <code>add</code> method.
	 * @param title the title of the commit set
	 * @param diffs the files contained in the set
	 * @return the created set
	 */
	public ActiveChangeSet createSet(String title, IDiff[] diffs) {
		ActiveChangeSet commitSet = doCreateSet(title);
		if (diffs != null && diffs.length > 0) {
			commitSet.add(diffs);
		}
		return commitSet;
	}

	/**
	 * Create a change set with the given name.
	 * @param name the name of the change set
	 * @return the created change set
	 */
	protected ActiveChangeSet doCreateSet(String name) {
		return new ActiveChangeSet(this, name);
	}

	public abstract IDiff getDiff(IResource resource) throws CoreException;

	/**
	 * Return whether the manager allows a resource to
	 * be in multiple sets. By default, a resource
	 * may only be in one set.
	 * @return whether the manager allows a resource to
	 * be in multiple sets.
	 */
	protected boolean isSingleSetPerResource() {
		return true;
	}

	private IPath[] getAllResources(IDiffChangeEvent event) {
		Set<IPath> allResources = new HashSet<>();
		IDiff[] addedResources = event.getAdditions();
		for (int i = 0; i < addedResources.length; i++) {
			IDiff diff = addedResources[i];
			allResources.add(diff.getPath());
		}
		IDiff[] changedResources = event.getChanges();
		for (int i = 0; i < changedResources.length; i++) {
			IDiff diff = changedResources[i];
			allResources.add(diff.getPath());
		}
		IPath[] removals = event.getRemovals();
		for (int i = 0; i < removals.length; i++) {
			IPath path = removals[i];
			allResources.add(path);
		}
		return allResources.toArray(new IPath[allResources.size()]);
	}

	/**
	 * React to the given diffs being added to the given set.
	 * @param set the set
	 * @param diffs the diffs
	 */
	protected void handleAddedResources(ChangeSet set, IDiff[] diffs) {
		if (isSingleSetPerResource() && ((ActiveChangeSet)set).isUserCreated()) {
			IResource[] resources = new IResource[diffs.length];
			for (int i = 0; i < resources.length; i++) {
				resources[i] = ((DiffChangeSet)set).getDiffTree().getResource(diffs[i]);
			}
			// Remove the added files from any other set that contains them
			ChangeSet[] sets = getSets();
			for (int i = 0; i < sets.length; i++) {
				ChangeSet otherSet = sets[i];
				if (otherSet != set && ((ActiveChangeSet)otherSet).isUserCreated()) {
					otherSet.remove(resources);
				}
			}
		}
	}

	private void handleSyncSetChange(IResourceDiffTree tree, IDiff[] addedDiffs, IPath[] allAffectedResources) {
		ChangeSet changeSet = getChangeSet(tree);
		if (tree.isEmpty() && changeSet != null) {
			remove(changeSet);
		}
		fireResourcesChangedEvent(changeSet, allAffectedResources);
		handleAddedResources(changeSet, addedDiffs);
	}

	/**
	 * Make the given set the default set into which all new modifications that
	 * are not already in another set go.
	 *
	 * @param set
	 *            the set which is to become the default set or
	 *            <code>null</code> to unset the default set
	 */
	public void makeDefault(ActiveChangeSet set) {
		// The default set must be an active set
		if (set != null && !contains(set)) {
			add(set);
		}
		ActiveChangeSet oldSet = defaultSet;
		defaultSet = set;
		fireDefaultChangedEvent(oldSet, defaultSet);
	}

	/**
	 * Return whether the given set is the default set into which all
	 * new modifications will be placed.
	 * @param set the set to test
	 * @return whether the set is the default set
	 */
	public boolean isDefault(ActiveChangeSet set) {
		return set == defaultSet;
	}

	/**
	 * Return the set which is currently the default or
	 * <code>null</code> if there is no default set.
	 * @return the default change set
	 */
	public ActiveChangeSet getDefaultSet() {
		return defaultSet;
	}

	/**
	 * If the given traversals contain any resources in the active change sets, ensure
	 * that the traversals cover all the resources in the overlapping change set.
	 * @param traversals the traversals
	 * @return the traversals adjusted to contain all the resources of intersecting change sets
	 */
	public ResourceTraversal[] adjustInputTraversals(ResourceTraversal[] traversals) {
		CompoundResourceTraversal traversal = new CompoundResourceTraversal();
		traversal.addTraversals(traversals);
		ChangeSet[] sets = getSets();
		for (int i = 0; i < sets.length; i++) {
			ChangeSet set = sets[i];
			handleIntersect(traversal, set);
		}
		return traversal.asTraversals();
	}

	private void handleIntersect(CompoundResourceTraversal traversal, ChangeSet set) {
		IResource[] resources = set.getResources();
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			if (traversal.isCovered(resource, IResource.DEPTH_ZERO)) {
				traversal.addResources(resources, IResource.DEPTH_ZERO);
				return;
			}
		}
	}

	/**
	 * Save the state of this manager including all its contained sets
	 * into the given preferences node.
	 * @param prefs a preferences node
	 */
	protected void save(Preferences prefs) {
		// No need to save the sets if the manager has never been initialized
		if (!isInitialized())
			return;
		// Clear the persisted state before saving the new state
		try {
			String[] oldSetNames = prefs.childrenNames();
			for (int i = 0; i < oldSetNames.length; i++) {
				String string = oldSetNames[i];
				prefs.node(string).removeNode();
			}
		} catch (BackingStoreException e) {
			TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.SubscriberChangeSetCollector_5, new String[] { getName() }), e);
		}
		ChangeSet[] sets = getSets();
		for (int i = 0; i < sets.length; i++) {
			ChangeSet set = sets[i];
			if (set instanceof ActiveChangeSet && !set.isEmpty()) {
				// Since the change set title is stored explicitly, the name of
				// the child preference node doesn't matter as long as it
				// doesn't contain / and no two change sets get the same name.
				String childPrefName = escapePrefName(((ActiveChangeSet)set).getTitle());
				Preferences child = prefs.node(childPrefName);
				((ActiveChangeSet)set).save(child);
			}
		}
		if (getDefaultSet() != null) {
			prefs.put(CTX_DEFAULT_SET, getDefaultSet().getTitle());
		} else {
			// unset default changeset
			prefs.remove(CTX_DEFAULT_SET);
		}
		try {
			prefs.flush();
		} catch (BackingStoreException e) {
			TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.SubscriberChangeSetCollector_3, new String[] { getName() }), e);
		}
	}

	/**
	 * Escape the given string for safe use as a preference node name by
	 * translating / to \s (so it's a single path component) and \ to \\ (to
	 * preserve uniqueness).
	 *
	 * @param string
	 *            Input string
	 * @return Escaped output string
	 */
	private static String escapePrefName(String string) {
		StringBuilder out = new StringBuilder();
		for (int i = 0; i < string.length(); i++) {
			char c = string.charAt(i);
			switch (c) {
			case '/':
				out.append("\\s"); //$NON-NLS-1$
				break;
			case '\\':
				out.append("\\\\"); //$NON-NLS-1$
				break;
			default:
				out.append(c);
			}
		}
		return out.toString();
	}

	/**
	 * Load the manager's state from the given preferences node.
	 *
	 * @param prefs
	 *            a preferences node
	 */
	protected void load(Preferences prefs) {
		String defaultSetTitle = prefs.get(CTX_DEFAULT_SET, null);
		try {
			String[] childNames = prefs.childrenNames();
			for (int i = 0; i < childNames.length; i++) {
				String string = childNames[i];
				Preferences childPrefs = prefs.node(string);
				ActiveChangeSet set = createSet(childPrefs);
				if (!set.isEmpty()) {
					if (getDefaultSet() == null && defaultSetTitle != null && set.getTitle().equals(defaultSetTitle)) {
						makeDefault(set);
					}
					add(set);
				}
			}
		} catch (BackingStoreException e) {
			TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.SubscriberChangeSetCollector_4, new String[] { getName() }), e);
		}
	}

	/**
	 * Return the name of this change set manager.
	 * @return the name of this change set manager
	 */
	protected abstract String getName();

	/**
	 * Create a change set from the given preferences that were
	 * previously saved.
	 * @param childPrefs the previously saved preferences
	 * @return the created change set
	 */
	protected ActiveChangeSet createSet(Preferences childPrefs) {
		// Don't specify a title when creating the change set; instead, let the
		// change set read its title from the preferences.
		ActiveChangeSet changeSet = doCreateSet(null);
		changeSet.init(childPrefs);
		return changeSet;
	}

	@Override
	public void ensureChangesGrouped(IProject project, IFile[] files,
			String name) throws CoreException {
		ActiveChangeSet set = getSet(name);
		if (set == null) {
			set = createSet(name, files);
			set.setUserCreated(false);
			add(set);
		} else {
			set.setUserCreated(false);
			set.add(files);
		}
	}
}
