/*******************************************************************************
 * Copyright (c) 2009 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.debug.core;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.internal.core.DebugCoreMessages;
import org.eclipse.debug.internal.core.IMementoConstants;
import org.eclipse.debug.internal.core.ResourceFactory;
import org.eclipse.debug.internal.core.XMLMemento;

import com.ibm.icu.text.MessageFormat;

/**
 * Utilities for launch configurations that persist, restore, and refresh
 * collections of resources.
 * 
 * @since 3.6
 * @noextend This class is not intended to be subclassed by clients.
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
public class RefreshUtil {

	/**
	 * String attribute identifying a scope of resources that should be
	 * refreshed - for example, after an external tool is run. The value is either
	 * a resource memento constant by this class, a resource memento created
	 * via {@link RefreshUtil#toMemento(IResource[])}, <code>null</code>, indicating no
	 * refresh.
	 */
	public static final String ATTR_REFRESH_SCOPE = DebugPlugin.getUniqueIdentifier() + ".ATTR_REFRESH_SCOPE"; //$NON-NLS-1$

	/**
	 * Boolean attribute indicating if a refresh scope is recursive. Default
	 * value is <code>true</code>. When a refresh is recursive, resources are
	 * refreshed to an infinite depth, otherwise they are refreshed to a depth
	 * of one.
	 */
	public static final String ATTR_REFRESH_RECURSIVE = DebugPlugin.getUniqueIdentifier() + ".ATTR_REFRESH_RECURSIVE"; //$NON-NLS-1$
	
	/**
	 * Resource memento referring to the selected resource's project.
	 * Only works when the debug user interface is running.
	 * 
	 * @see #toResources(String)
	 */
	public static final String MEMENTO_SELECTED_PROJECT = "${project}"; //$NON-NLS-1$
	
	/**
	 * Resource memento referring to the selected resource's container.
	 * Only works when the debug user interface is running.
	 * 
	 * @see #toResources(String)
	 */	
	public static final String MEMENTO_SELECTED_CONTAINER = "${container}"; //$NON-NLS-1$
	
	/**
	 * Resource memento referring to the selected resource.
	 * Only works when the debug user interface is running.
	 * 
	 * @see #toResources(String)
	 */	
	public static final String MEMENTO_SELECTED_RESOURCE = "${resource}"; //$NON-NLS-1$
	
	/**
	 * Resource memento referring to the workspace root.
	 * 
	 * @see #toResources(String)
	 */	
	public static final String MEMENTO_WORKSPACE = "${workspace}"; //$NON-NLS-1$
	
	/**
	 *  Indicates no working set has been selected (for backwards compatibility).
	 *  The new format uses an empty working set
	 */
	
	private static final String NO_WORKING_SET = "NONE"; //$NON-NLS-1$

	/**
	 * Refreshes the resources as specified by the given launch configuration.
	 * 
	 * @param resources
	 *            resources to refresh
	 * @param depth one of {@link IResource#DEPTH_INFINITE}, {@link IResource#DEPTH_ONE},
	 *  or {@link IResource#DEPTH_ZERO} 
	 * @param monitor
	 *            progress monitor which may be <code>null</code>
	 * @throws CoreException
	 *             if an exception occurs while refreshing resources
	 */
	public static void refreshResources(IResource[] resources, int depth, IProgressMonitor monitor) throws CoreException {
		if (monitor == null) {
			monitor = new NullProgressMonitor();
		}
		if (resources == null || resources.length == 0) {
			return;
		}
		if (monitor.isCanceled()) {
			return;
		}
		monitor.beginTask(DebugCoreMessages.RefreshingResources, resources.length);
		MultiStatus status = new MultiStatus(DebugPlugin.getUniqueIdentifier(), 0, DebugCoreMessages.RefreshingResourcesError, null);
		for (int i = 0; i < resources.length; i++) {
			if (monitor.isCanceled())
				break;
			if (resources[i] != null && resources[i].isAccessible()) {
				try {
					resources[i].refreshLocal(depth, null);
				} catch (CoreException e) {
					status.merge(e.getStatus());
				}
			}
			monitor.worked(1);
		}
		monitor.done();
		if (!status.isOK()) {
			throw new CoreException(status);
		}
	}

	/**
	 * Returns a collection of resources referred to by the specified
	 * memento generated via {@link #toMemento(IResource[])}.
	 * 
	 * @param memento
	 *            resource memento generated by this manager
	 * @return collection of resources referred to by the memento
	 * @throws CoreException
	 *             if unable to resolve a set of resources
	 */
	public static IResource[] toResources(String memento) throws CoreException {
		if (memento.startsWith("${resource:")) { //$NON-NLS-1$
			// This is an old format that is replaced with 'working_set'
			String pathString = memento.substring(11, memento.length() - 1);
			Path path = new Path(pathString);
			IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
			if (resource == null) {
				throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
						IStatus.ERROR, MessageFormat.format(DebugCoreMessages.RefreshUtil_1,
								new String[] { pathString }), null));
			}
			return new IResource[] { resource };
		} else if (memento.startsWith("${working_set:")) { //$NON-NLS-1$
			String ws = memento.substring(14, memento.length() - 1);
			return getResources(ws);
		} else if (memento.equals(MEMENTO_WORKSPACE)) {
			return new IResource[] { ResourcesPlugin.getWorkspace().getRoot() };
		} else {
			// result the selected resource for backwards compatibility
			IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
			IResource resource = null;
			try {
				String pathString = manager.performStringSubstitution("${selected_resource_path}"); //$NON-NLS-1$
				resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(pathString));
			} catch (CoreException e) {
				// unable to resolve a resource
			}
			if (resource == null) {
				// empty selection
				return new IResource[]{};
			} else {
				if (memento.equals(MEMENTO_SELECTED_RESOURCE)) {
					return new IResource[] { resource };
				} else if (memento.equals(MEMENTO_SELECTED_CONTAINER)) {
					return new IResource[] {resource.getParent()};
				} else if (memento.equals(MEMENTO_SELECTED_PROJECT)) {
					return new IResource[] {resource.getProject()};
				}
			}
		}
		throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), MessageFormat.format(DebugCoreMessages.RefreshUtil_0, new String[]{memento})));
	}
	
	/**
	 * Returns a memento for a collection of resources that can be restored
	 * via {@link #toResources(String)}.
	 * 
	 * @param resources resources to create a memento for
	 * @return memento for the given resources
	 */
	public static String toMemento(IResource[] resources) {
		XMLMemento memento = XMLMemento.createWriteRoot("resources"); //$NON-NLS-1$
		for (int i = 0; i < resources.length; i++) {
			final XMLMemento itemMemento = memento.createChild(IMementoConstants.MEMENTO_ITEM);
			ResourceFactory.saveState(itemMemento, resources[i]);
		}
		StringWriter writer = new StringWriter();
		try {
			memento.save(writer);
		} catch (IOException e) {
			DebugPlugin.log(e);
		}
		StringBuffer buf = new StringBuffer();
		buf.append("${working_set:"); //$NON-NLS-1$
		buf.append(writer.toString());
		buf.append("}"); //$NON-NLS-1$
		return buf.toString();
	}
	
	/**
	 * Restores a collection of resources from a working set memento, for backwards
	 * compatibility.
	 * 
	 * @param wsMemento working set memento
	 * @return resource collection, possibly empty
	 */
	private static IResource[] getResources(String wsMemento) {

		if (NO_WORKING_SET.equals(wsMemento)) {
			return null;
		}

		List resourcesList = new ArrayList();
		StringReader reader = new StringReader(wsMemento);

		XMLMemento memento = null;
		try {
			memento = XMLMemento.createReadRoot(reader);
		} catch (Exception e) {
			DebugPlugin.log(e);
			return null;
		}

		XMLMemento[] mementos = memento
				.getChildren(IMementoConstants.MEMENTO_ITEM);
		for (int i = 0; i < mementos.length; i++) {
			resourcesList.add(ResourceFactory.createElement(mementos[i]));
		}

		return (IResource[]) resourcesList.toArray(new IResource[resourcesList.size()]);

	}	
	
	/**
	 * Returns whether the refresh scope specified by the given launch
	 * configuration is recursive.
	 * 
	 * @param configuration
	 * @return whether the refresh scope is recursive
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static  boolean isRefreshRecursive(ILaunchConfiguration configuration) throws CoreException {
		return configuration.getAttribute(ATTR_REFRESH_RECURSIVE, true);
	}	
	
	/**
	 * Refreshes the resources as specified by the given launch configuration via its
	 * {@link RefreshUtil#ATTR_REFRESH_SCOPE} and {@link #ATTR_REFRESH_RECURSIVE} attributes.
	 * 
	 * @param configuration launch configuration
	 * @param monitor progress monitor which may be <code>null</code>
	 * @throws CoreException
	 *             if an exception occurs while refreshing resources or accessing launch
	 *             configuration attributes
	 */
	public static void refreshResources(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
		String scope = configuration.getAttribute(ATTR_REFRESH_SCOPE, (String) null);
		if (scope != null) {
			IResource[] resources = toResources(scope);
			if (resources != null && resources.length > 0) {
				int depth = IResource.DEPTH_ONE;
				if (isRefreshRecursive(configuration)) {
					depth = IResource.DEPTH_INFINITE;
				}
				refreshResources(resources, depth, monitor);
			}
		}
	}	
}
