/*******************************************************************************
 * Copyright (c) 2000, 2007 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.internal.core;

 
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
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.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;

import com.ibm.icu.text.MessageFormat;

/**
 * A working copy launch configuration
 */
public class LaunchConfigurationWorkingCopy extends LaunchConfiguration implements ILaunchConfigurationWorkingCopy {
	
	/**
	 * Handle of original launch configuration this
	 * working copy is based on
	 */
	private LaunchConfiguration fOriginal;
	
	/**
	 * Handle to a parent working copy
	 * @since 3.3
	 */
	private LaunchConfigurationWorkingCopy fParent =  null;
	
	/**
	 * Working copy of attributes.
	 */
	private LaunchConfigurationInfo fInfo;
	
	/**
	 * Whether this working copy has been modified since
	 * it was created
	 */
	private boolean fDirty = false;
	
	/**
	 * The name for this configuration.
	 */
	private String fName;
	
	/**
	 * Indicates whether this working copy has been explicitly renamed.
	 */
	private boolean fRenamed = false;
	
	/**
	 * Suppress change notification until created
	 */
	private boolean fSuppressChange = true;
	
	/**
	 * The container this working copy will be
	 * stored in when saved.
	 */
	private IContainer fContainer;
	
	/**
	 * Constructs a working copy of the specified launch 
	 * configuration.
	 * 
	 * @param original launch configuration to make
	 *  a working copy of
	 * @exception CoreException if unable to initialize this
	 *  working copy's attributes based on the original configuration
	 */
	protected LaunchConfigurationWorkingCopy(LaunchConfiguration original) throws CoreException {
		super(original.getLocation());
		setName(original.getName());
		copyFrom(original);
		setOriginal(original);
		fSuppressChange = false;
	}
	
	/**
	 * Constructs a working copy of the specified launch configuration as its parent.
	 * 
	 * @param parent launch configuration to make
	 *  a working copy of
	 * @exception CoreException if unable to initialize this
	 *  working copy's attributes based on the original configuration
	 */
	protected LaunchConfigurationWorkingCopy(LaunchConfigurationWorkingCopy parent) throws CoreException {
		super(parent.getLocation());
		setName(parent.getName());
		copyFrom(parent);
		setOriginal((LaunchConfiguration) parent.getOriginal());
		fParent = parent;
		fSuppressChange = false;
	}	
	
	/**
	 * Constructs a copy of the specified launch 
	 * configuration, with the given (new) name.
	 * 
	 * @param original launch configuration to make
	 *  a working copy of
	 * @param name the new name for the copy of the launch
	 *  configuration
	 * @exception CoreException if unable to initialize this
	 *  working copy's attributes based on the original configuration
	 */
	protected LaunchConfigurationWorkingCopy(LaunchConfiguration original, String name) throws CoreException {
		super(original.getLocation());
		copyFrom(original);
		setName(name);
		fSuppressChange = false;
	}
	
	/**
	 * Constructs a new working copy to be created in the specified
	 * location.
	 * 
	 * @param container the container that the configuration will be created in
	 *  or <code>null</code> if to be local
	 * @param name the name of the new launch configuration
	 * @param type the type of this working copy
	 */
	protected LaunchConfigurationWorkingCopy(IContainer container, String name, ILaunchConfigurationType type) {
		super((IPath)null);
		setName(name);
		setInfo(new LaunchConfigurationInfo());
		getInfo().setType(type);
		setContainer(container);
		fSuppressChange = false;
	}

	/**
	 * @see ILaunchConfigurationWorkingCopy#isDirty()
	 */
	public boolean isDirty() {
		return fDirty;
	}

	/**
	 * @see ILaunchConfigurationWorkingCopy#doSave()
	 */
	public synchronized ILaunchConfiguration doSave() throws CoreException {
		return doSave(new NullProgressMonitor());
	}

	/**
	 * Saves with progress.
	 * 
	 * @param monitor
	 * @return the saved <code>ILaunchConfiguration</code>
	 * @throws CoreException
	 * 
	 * @since 3.3
	 */
	public synchronized ILaunchConfiguration doSave(IProgressMonitor monitor) throws CoreException {
		if (getParent() != null) {
			// save to parent working copy
			LaunchConfigurationWorkingCopy wc = (LaunchConfigurationWorkingCopy) getParent();
			if(isMoved()) {
				wc.rename(getName());
				wc.setContainer(getContainer());
			}
			wc.setAttributes(getInfo().getAttributes());
			return wc;
		}
		else {
			boolean useRunnable= true;
			if (isLocal()) {
				if (isMoved()) {
					// If this config was moved from a shared location, saving
					// it will delete the original from the workspace. Use runnable.
					useRunnable= !isNew() && !getOriginal().isLocal();
				} else {
					useRunnable= false;
				}
			}
			if (useRunnable) {
				IWorkspaceRunnable wr = new IWorkspaceRunnable() {
					public void run(IProgressMonitor pm) throws CoreException {
						doSave0(pm);
					}
				};
				ResourcesPlugin.getWorkspace().run(wr, null, 0, monitor);
			} else {
				//file is persisted in the metadata not the workspace
				doSave0(monitor);
			}
			getLaunchManager().setMovedFromTo(null, null);
		}
		return new LaunchConfiguration(getLocation());
	}
	
	/**
	 * Performs the actual saving of the launch configuration.
	 * @throws CoreException
	 */
	private void doSave0(IProgressMonitor monitor) throws CoreException {
		// set up from/to information if this is a move
		boolean moved = (!isNew() && isMoved());
		if (moved) {
			ILaunchConfiguration to = new LaunchConfiguration(getLocation());
			ILaunchConfiguration from = getOriginal();
			getLaunchManager().setMovedFromTo(from, to);
		}
		// delete the old file if this is not a new configuration
		// or the file was renamed/moved
		if (moved) {
			getOriginal().delete();
		}
		// write the new file
		if(monitor == null) {
			monitor = new NullProgressMonitor();
		}
		monitor.beginTask(MessageFormat.format(DebugCoreMessages.LaunchConfigurationWorkingCopy_0, new String[] {getName()}), 2);
		writeNewFile(monitor);
		monitor.done();
		fDirty = false;
	}
	
	/**
	 * Writes the new configuration information to a file.
	 * 
	 * @exception CoreException if writing the file fails
	 */
	protected void writeNewFile(IProgressMonitor monitor) throws CoreException {
		String xml = null;
		Exception e= null;
		try {
			xml = getInfo().getAsXML();
		} catch (IOException ioe) {
			e= ioe;			
		} catch (ParserConfigurationException pce) {
			e= pce;
		} catch (TransformerException te) {
			e= te;		
		}
		if (e != null) {
			throw new DebugException(
				new Status(
					IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
					DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.LaunchConfigurationWorkingCopy__0__occurred_generating_launch_configuration_XML__1, new String[]{e.toString()}), null 
					)
				);		
		}
		
		if (isLocal()) {
			// use java.io to update configuration file
			try {
				boolean added = false;
				monitor.subTask(DebugCoreMessages.LaunchConfigurationWorkingCopy_1);
				File file = getLocation().toFile();
				File dir = getLocation().removeLastSegments(1).toFile();
				dir.mkdirs();
				if (!file.exists()) {
					added = true;
					file.createNewFile();
					monitor.worked(1);
				}
				FileOutputStream stream = new FileOutputStream(file);
				stream.write(xml.getBytes("UTF8")); //$NON-NLS-1$
				stream.close();
				
				if (added) {
					getLaunchManager().launchConfigurationAdded(new LaunchConfiguration(getLocation()));
				} else {
					getLaunchManager().launchConfigurationChanged(new LaunchConfiguration(getLocation()));
				}
				//notify file saved
				monitor.worked(1);
			} catch (IOException ie) {
				monitor.setCanceled(true);
				throw new DebugException(
					new Status(
					 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
					 DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.LaunchConfigurationWorkingCopy__0__occurred_generating_launch_configuration_XML__1, new String[]{ie.toString()}), null 
					)
				);				
			}
		} else {
			// use resource API to update configuration file
			IFile file = getFile();
			if (file == null) {
				monitor.setCanceled(true);
				throw new DebugException(
						new Status(
							 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
							 DebugException.REQUEST_FAILED, DebugCoreMessages.LaunchConfigurationWorkingCopy_5, null 
						));
			}
			IContainer dir = file.getParent();
			if (!dir.exists()) {
				monitor.setCanceled(true);
				throw new DebugException(
					new Status(
					 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
					 DebugException.REQUEST_FAILED, DebugCoreMessages.LaunchConfigurationWorkingCopy_Specified_container_for_launch_configuration_does_not_exist_2, null 
					)
				);				
			}
			ByteArrayInputStream stream = null;
			try {
				stream = new ByteArrayInputStream(xml.getBytes("UTF8")); //$NON-NLS-1$
			} catch (UnsupportedEncodingException ue) {
				monitor.setCanceled(true);
				throw new DebugException(
					new Status(
						 IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
						 DebugException.REQUEST_FAILED, DebugCoreMessages.LaunchConfigurationWorkingCopy_5, ue 
					));
			}
			SubProgressMonitor spm = null;
			if (!file.exists()) {
	//create file input stream: work one unit in a sub monitor
				spm = new SubProgressMonitor(monitor, 1);
				spm.setTaskName(MessageFormat.format(DebugCoreMessages.LaunchConfigurationWorkingCopy_2, new String[] {getName()}));
				file.create(stream, false, spm);
			} else {
				// validate edit
				if (file.isReadOnly()) {
					IStatus status = ResourcesPlugin.getWorkspace().validateEdit(new IFile[] {file}, null);
					if (!status.isOK()) {
						monitor.setCanceled(true);
						throw new CoreException(status);
					}
				}				
	//set the contents of the file: work 1 unit in a sub monitor
				spm = new SubProgressMonitor(monitor, 1);
				spm.setTaskName(MessageFormat.format(DebugCoreMessages.LaunchConfigurationWorkingCopy_3, new String[] {getName()}));
				file.setContents(stream, true, false, spm);
			}
		}
		if(monitor.isCanceled()) {
			return;
		}
	}

	/**
	 * @see ILaunchConfigurationWorkingCopy#setAttribute(String, int)
	 */
	public void setAttribute(String attributeName, int value) {
		getInfo().setAttribute(attributeName, new Integer(value));
		setDirty();
	}

	/**
	 * @see ILaunchConfigurationWorkingCopy#setAttribute(String, String)
	 */
	public void setAttribute(String attributeName, String value) {
		getInfo().setAttribute(attributeName, value);
		setDirty();
	}

	/**
	 * @see ILaunchConfigurationWorkingCopy#setAttribute(String, boolean)
	 */
	public void setAttribute(String attributeName, boolean value) {
		getInfo().setAttribute(attributeName, Boolean.valueOf(value));
		setDirty();	
	}

	/**
	 * @see ILaunchConfigurationWorkingCopy#setAttribute(String, List)
	 */
	public void setAttribute(String attributeName, List value) {
		getInfo().setAttribute(attributeName, value);
		setDirty();
	}

	/**
	 * @see ILaunchConfigurationWorkingCopy#setAttribute(String, Map)
	 */
	public void setAttribute(String attributeName, Map value) {
		getInfo().setAttribute(attributeName, value);
		setDirty();
	}

	/**
	 * @see ILaunchConfigurationWorkingCopy#getOriginal()
	 */
	public ILaunchConfiguration getOriginal() {
		ILaunchConfiguration config = fOriginal;
		ILaunchConfigurationWorkingCopy parent = fParent;
		while(parent != null) {
			config = parent.getOriginal();
			parent = parent.getParent();
		}
		return config;
	}
	
	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#getParent()
	 */
	public ILaunchConfigurationWorkingCopy getParent() {
		return fParent;
	}
	
	/**
	 * Sets the launch configuration this working copy
	 * is based on. Initializes the attributes of this
	 * working copy to the current values of the given
	 * configuration.
	 * 
	 * @param original the launch configuration this working
	 *  copy is based on.
	 * @exception CoreException if unable to initialize this
	 *  working copy based on the original's current attribute
	 *  set
	 */
	private void copyFrom(LaunchConfiguration original) throws CoreException {
		LaunchConfigurationInfo info = original.getInfo();
		setInfo(info.getCopy());
		setContainer(original.getContainer());
		fDirty = false;
	}
	
	/**
	 * Sets the launch configuration this working copy
	 * is based on.
	 * 
	 * @param original the launch configuration this working 
	 *  copy is based on.
	 */
	private void setOriginal(LaunchConfiguration original) {
		fOriginal = original;
	}	
	
	/**
	 * Sets the working copy info object for this working copy.
	 * 
	 * @param info a copy of attributes from this working copy's
	 * 	original launch configuration
	 */
	protected void setInfo(LaunchConfigurationInfo info) {
		fInfo = info;
	}

	/**
	 * @see ILaunchConfiguration#isWorkingCopy()
	 */
	public boolean isWorkingCopy() {
		return true;
	}
	
	/**
	 * A working copy keeps a local info object that is not
	 * cached with the launch manager.
	 * 
	 * @see LaunchConfiguration#getInfo()
	 */
	protected LaunchConfigurationInfo getInfo() {
		return fInfo;
	}
	
	/**
	 * Sets this working copy's state to dirty.
	 * Notifies listeners that this working copy has
	 * changed.
	 */
	private void setDirty() {
		fDirty = true;
		if (!suppressChangeNotification()) {
			getLaunchManager().getConfigurationNotifier().notify(this, LaunchManager.CHANGED);
		}	
	}
		
	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#setModes(java.util.Set)
	 */
	public void setModes(Set modes) {
		getInfo().setAttribute(ATTR_LAUNCH_MODES, (modes.size() > 0 ? modes : null));
		setDirty();
	}

	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#addModes(java.util.Set)
	 */
	public void addModes(Set modes) {
		try {
			Set opts = getModes();
			if(opts.addAll(modes)) {
				getInfo().setAttribute(ATTR_LAUNCH_MODES, opts);
				setDirty();
			}
		} 
		catch (CoreException e) {
			DebugPlugin.log(e);
		}
	}
	
	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#removeModes(java.util.Set)
	 */
	public void removeModes(Set options) {
		try {
			Set opts = getModes();
			if(opts.removeAll(options)) {
				getInfo().setAttribute(ATTR_LAUNCH_MODES, (opts.size() < 1 ? null : opts));
				setDirty();
			}
		} 
		catch (CoreException e) {
			DebugPlugin.log(e);
		}
	}
	
	/**
	 * @see ILaunchConfigurationWorkingCopy#rename(String)
	 */
	public void rename(String name) {
		if (!getName().equals(name)) {
			setName(name);
			fRenamed = isNew() || !(getOriginal().getName().equals(name));
		}
	}

	/**
	 * Sets the new name for this configuration.
	 * 
	 * @param name the new name for this configuration
	 */
	private void setName(String name) {
		fName = name;
		setDirty();
	}
	
	/**
	 * @see ILaunchConfiguration#getName()
	 */
	public String getName() {
		return fName;
	}
	
	/**
	 * @see ILaunchConfiguration#isLocal()
	 */
	public boolean isLocal() {
		return getContainer() == null;
	}	
	
	/**
	 * Returns the location this launch configuration will reside at
	 * when saved.
	 * 
	 * @see ILaunchConfiguration#getLocation()
	 */
	public IPath getLocation() {
		if (isMoved()) {
			IPath path = null;
			if (isLocal()) {
				path = LaunchManager.LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH;
			} else {
				path = getContainer().getLocation();
			}
			path = path.append(getName() + "." + LAUNCH_CONFIGURATION_FILE_EXTENSION); //$NON-NLS-1$
			return path;
		} 
		return getOriginal().getLocation();
	}
	
	/**
	 * Returns whether this working copy is new, or is a
	 * working copy of another launch configuration.
	 * 
	 * @return whether this working copy is new, or is a
	 *  working copy of another launch configuration
	 */
	protected boolean isNew() {
		return getOriginal() == null;
	}
	
	/**
	 * Returns whether this working copy is new or if its
	 * location has changed from that of its original.
	 * 
	 * @return whether this working copy is new or if its
	 * location has changed from that of its original
	 */
	protected boolean isMoved() {
		if (isNew() || fRenamed) {
			return true;
		}
		IContainer newContainer = getContainer();
		IContainer originalContainer = ((LaunchConfiguration)getOriginal()).getContainer();
		if (newContainer == originalContainer) {
			return false;
		}
		if (newContainer == null) {
			return !originalContainer.equals(newContainer);
		} 
		return !newContainer.equals(originalContainer);
	}		
	
	/**
	 * A working copy cannot generate a memento.
	 * 
	 * @see ILaunchConfiguration#getMemento()
	 */
	public String getMemento() {
		return null;
	}	
	
	/**
	 * Returns whether change notification should be
	 * suppressed
	 */
	protected boolean suppressChangeNotification() {
		return fSuppressChange;
	}
	
	/**
	 * @see ILaunchConfigurationWorkingCopy#setContainer(IContainer)
	 */
	public void setContainer(IContainer container) {
		if (container == fContainer) {
			return;
		}
		if (container != null) {
			if (container.equals(fContainer)) {
				return;
			}
		} else {
			if (fContainer.equals(container)) {
				return;
			}
		}
		fContainer = container;
		setDirty();
	}
	
	/**
	 * Returns the container this working copy will be
	 * stored in when saved, or <code>null</code> if
	 * this working copy is local.
	 * 
	 * @return the container this working copy will be
	 *  stored in when saved, or <code>null</code> if
	 *  this working copy is local
	 */
	protected IContainer getContainer() {
		return fContainer;
	}	
	
	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#setAttributes(java.util.Map)
	 */
	public void setAttributes(Map attributes) {
		getInfo().setAttributes(attributes);
		setDirty();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#setResource(org.eclipse.core.resources.IResource)
	 */
	public void setMappedResources(IResource[] resources) {
		ArrayList paths = null;
		ArrayList types = null;
		if(resources != null && resources.length > 0) {
			paths = new ArrayList(resources.length);
			types = new ArrayList(resources.length);
			for (int i = 0; i < resources.length; i++) {
				IResource resource = resources[i];
				if(resource != null) {
					paths.add(resource.getFullPath().toPortableString());
					types.add(new Integer(resource.getType()).toString());
				}
			}
		}
		setAttribute(LaunchConfiguration.ATTR_MAPPED_RESOURCE_PATHS, paths);
		setAttribute(LaunchConfiguration.ATTR_MAPPED_RESOURCE_TYPES, types);
	}

	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#setPreferredLaunchDelegate(java.util.Set, java.lang.String)
	 */
	public void setPreferredLaunchDelegate(Set modes, String delegateId) {
		if(modes != null) {
			try {
				Map delegates = getAttribute(LaunchConfiguration.ATTR_PREFERRED_LAUNCHERS, (Map)null);
					//copy map to avoid pointer issues
					Map map = new HashMap();
					if(delegates != null) {
						map.putAll(delegates);
					}
					if(delegateId == null) {
						map.remove(modes.toString());
					}
					else {
						map.put(modes.toString(), delegateId);
					}
					setAttribute(LaunchConfiguration.ATTR_PREFERRED_LAUNCHERS, map);
			}
			catch (CoreException ce) {DebugPlugin.log(ce);}
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.LaunchConfiguration#getWorkingCopy()
	 * CONTEXTLAUNCHING
	 */
	public ILaunchConfigurationWorkingCopy getWorkingCopy() throws CoreException {
		return new LaunchConfigurationWorkingCopy(this);
	}
}

