/*******************************************************************************
 * Copyright (c) 2005, 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
 *     Sebastian Schmidt - bug 384460
 *******************************************************************************/

package org.eclipse.debug.ui.actions;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IBreakpointImportParticipant;
import org.eclipse.debug.internal.core.BreakpointManager;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.importexport.breakpoints.IImportExportConstants;
import org.eclipse.debug.internal.ui.importexport.breakpoints.ImportExportMessages;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;

import com.ibm.icu.text.MessageFormat;

/**
 * Imports breakpoints from a file or string buffer into the workspace.
 * <p>
 * This class may be instantiated.
 * <p>
 * @since 3.2
 * @noextend This class is not intended to be subclassed by clients.
 */
public class ImportBreakpointsOperation implements IRunnableWithProgress {

	private boolean fOverwriteAll = false;

	private String fFileName = null;

	private boolean fCreateWorkingSets = false;

	private ArrayList<IBreakpoint> fAdded = new ArrayList<IBreakpoint>();
	
	private String fCurrentWorkingSetProperty = null;

	private BreakpointManager fManager = (BreakpointManager) DebugPlugin.getDefault().getBreakpointManager();
	
	/** 
	 * When a buffer is specified, a file is not used.
	 */
	private StringBuffer fBuffer = null;

	private boolean fImportBreakpoints = true;

	/**
	 * Constructs an operation to import breakpoints.
	 * 
	 * @param fileName the file to read breakpoints from - the file should have been 
	 *            created from an export operation
	 * @param overwrite whether imported breakpoints will overwrite existing equivalent breakpoints
	 * @param createWorkingSets whether breakpoint working sets should be created. Breakpoints
	 * 	are exported with information about the breakpoint working sets they belong to. Those
	 * 	working sets can be optionally re-created on import if they do not already exist in the
	 *            workspace.
	 */
	public ImportBreakpointsOperation(String fileName, boolean overwrite, boolean createWorkingSets) {
		this(fileName, overwrite, createWorkingSets, true);
	}

	/**
	 * Constructs an operation to import breakpoints.
	 * 
	 * @param fileName the file to read breakpoints from - the file should have been created from an
	 *            export operation
	 * @param overwrite whether imported breakpoints will overwrite existing equivalent breakpoints
	 * @param createWorkingSets whether breakpoint working sets should be created. Breakpoints are
	 *            exported with information about the breakpoint working sets they belong to. Those
	 *            working sets can be optionally re-created on import if they do not already exist
	 *            in the workspace.
	 * @param importBreakpoints whether breakpoints should be imported and registered
	 * @since 3.9
	 */
	public ImportBreakpointsOperation(String fileName, boolean overwrite, boolean createWorkingSets, boolean importBreakpoints) {
		fFileName = fileName;
		fOverwriteAll = overwrite;
		fCreateWorkingSets = createWorkingSets;
		fImportBreakpoints = importBreakpoints;
	}
	
	/**
	 * Constructs an operation to import breakpoints from a string buffer. The buffer
	 * must contain a memento created an {@link ExportBreakpointsOperation}.
	 * 
	 * @param buffer the string buffer to read breakpoints from - the file should have been 
	 *            created from an export operation
	 * @param overwrite whether imported breakpoints will overwrite existing equivalent breakpoints
	 * @param createWorkingSets whether breakpoint working sets should be created. Breakpoints
	 * 	are exported with information about the breakpoint working sets they belong to. Those
	 * 	working sets can be optionally re-created on import if they do not already exist in the
	 *            workspace.
	 * @since 3.5
	 */
	public ImportBreakpointsOperation(StringBuffer buffer, boolean overwrite, boolean createWorkingSets) {
		this(buffer, overwrite, createWorkingSets, true);
	}
	
	/**
	 * Constructs an operation to import breakpoints from a string buffer. The buffer must contain a
	 * memento created an {@link ExportBreakpointsOperation}.
	 * 
	 * @param buffer the string buffer to read breakpoints from - the file should have been created
	 *            from an export operation
	 * @param overwrite whether imported breakpoints will overwrite existing equivalent breakpoints
	 * @param createWorkingSets whether breakpoint working sets should be created. Breakpoints are
	 *            exported with information about the breakpoint working sets they belong to. Those
	 *            working sets can be optionally re-created on import if they do not already exist
	 *            in the workspace.
	 * @param importBreakpoints whether breakpoints should be imported and registered
	 * @since 3.9
	 */
	public ImportBreakpointsOperation(StringBuffer buffer, boolean overwrite, boolean createWorkingSets, boolean importBreakpoints) {
		fBuffer = buffer;
		fOverwriteAll = overwrite;
		fCreateWorkingSets = createWorkingSets;
		fImportBreakpoints = importBreakpoints;
	}	

	/* (non-Javadoc)
	 * @see org.eclipse.core.resources.IWorkspaceRunnable#run(org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	public void run(final IProgressMonitor monitor) throws InvocationTargetException {
		SubMonitor localmonitor = SubMonitor.convert(monitor, ImportExportMessages.ImportOperation_0, 1);
		try {
			XMLMemento memento = null;
			if (fBuffer == null) {
				try (Reader reader = new InputStreamReader(new FileInputStream(fFileName), "UTF-8")) { //$NON-NLS-1$
					memento = XMLMemento.createReadRoot(reader);
				} catch (FileNotFoundException e) {
					throw new InvocationTargetException(e, MessageFormat.format("Breakpoint import file not found: {0}", new Object[] { //$NON-NLS-1$
							fFileName }));
				} catch (UnsupportedEncodingException e) {
					throw new InvocationTargetException(e, MessageFormat.format("The import file was written in non-UTF-8 encoding.", new Object[] { //$NON-NLS-1$
							fFileName }));
				} catch (IOException e) {
					throw new InvocationTargetException(e);
				}
			} else {
				try (Reader reader = new StringReader(fBuffer.toString())) {
					memento = XMLMemento.createReadRoot(reader);
				} catch (IOException e) {
					throw new InvocationTargetException(e);
				}
			}
			IMemento[] nodes = memento.getChildren(IImportExportConstants.IE_NODE_BREAKPOINT);
			IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot();
			localmonitor.setWorkRemaining(nodes.length);
			Map<String, Object> attributes = null;
			IBreakpointImportParticipant[] participants = null;
			for(int i = 0; i < nodes.length; i++) {
				if(localmonitor.isCanceled()) {
					return;
				}
				attributes = collectBreakpointProperties(nodes[i]);
				if(attributes == null) {
					continue;
				}
				IResource resource;
				if(fImportBreakpoints) {
					resource = workspace.findMember((String) attributes.get(IImportExportConstants.IE_NODE_PATH));
				} else {
					resource = workspace;
				}

				// filter resource breakpoints that do not exist in this workspace
				if(resource != null) {	
					try {
						participants = fManager.getImportParticipants((String) attributes.get(IImportExportConstants.IE_NODE_TYPE)); 
					}
					catch(CoreException ce) {}
					IMarker marker = findExistingMarker(attributes, participants);
					if(marker == null) {
						marker = resource.createMarker((String) attributes.get(IImportExportConstants.IE_NODE_TYPE));
						restoreBreakpoint(marker, attributes, participants);
					}
					else {
						if(fOverwriteAll) {
							if(!fImportBreakpoints) {
								marker = resource.createMarker((String) attributes.get(IImportExportConstants.IE_NODE_TYPE));
							} else {
								marker.setAttributes(null);
							}
							restoreBreakpoint(marker, attributes, participants);
						}
					}
				}
				fCurrentWorkingSetProperty = null;
				localmonitor.worked(1);
			}
			if(fAdded.size() > 0 && fImportBreakpoints) {
				fManager.addBreakpoints(fAdded.toArray(new IBreakpoint[fAdded.size()]));
			}
		} 
		catch(CoreException ce) {
			throw new InvocationTargetException(ce, 
 MessageFormat.format("There was a problem importing breakpoints from: {0}", new Object[] { fFileName })); //$NON-NLS-1$
		}
		finally {
			localmonitor.done();
		}
	}
	
	/**
	 * Returns a marker backing an existing breakpoint based on the given set of breakpoint attributes
	 * @param attributes the map of attributes to compare for marker equality
	 * @param participants the list of participants to ask if a breakpoint matches the given map of attributes
	 * @return the marker for an existing breakpoint or <code>null</code> if one could not be located
	 * @since 3.5
	 */
	protected IMarker findExistingMarker(Map<String, Object> attributes, IBreakpointImportParticipant[] participants) {
		IBreakpoint[] bps = fManager.getBreakpoints();		 
		for(int i = 0; i < bps.length; i++) {
			for(int j = 0; j < participants.length; j++) {
				try {
					if(participants[j].matches(attributes, bps[i])) {
						return bps[i].getMarker();
					}
				}
				catch(CoreException ce) {}
			}
		}
		return null;
	}
	
	/**
	 * Collects all of the properties for a breakpoint from the memento describing it.
	 * The values in the map will be one of:
	 * <ul>
	 * <li>{@link String}</li>
	 * <li>{@link Integer}</li>
	 * <li>{@link Boolean}</li>
	 * </ul>
	 * @param memento the memento to read breakpoint attributes from
	 * @return a new map of all of the breakpoint attributes from the given memento.
	 * @since 3.5
	 */
	protected Map<String, Object> collectBreakpointProperties(IMemento memento) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		
		//collect attributes from the 'breakpoint' node
		map.put(IImportExportConstants.IE_BP_ENABLED, memento.getBoolean(IImportExportConstants.IE_BP_ENABLED));
		map.put(IImportExportConstants.IE_BP_PERSISTANT, memento.getBoolean(IImportExportConstants.IE_BP_PERSISTANT));
		map.put(IImportExportConstants.IE_BP_REGISTERED, memento.getBoolean(IImportExportConstants.IE_BP_REGISTERED));

		//collect attributes from the 'marker' node
		IMemento child = memento.getChild(IImportExportConstants.IE_NODE_MARKER);
		map.put(IImportExportConstants.IE_NODE_TYPE, child.getString(IImportExportConstants.IE_NODE_TYPE));
		map.put(IMarker.LINE_NUMBER, child.getInteger(IMarker.LINE_NUMBER));

		//copy all the marker attributes to the map
		IMemento[] children = child.getChildren(IImportExportConstants.IE_NODE_ATTRIB);
		for(int i = 0; i < children.length; i++) {
			readAttribute(children[i], map);
		}

		//collect attributes from the 'resource' node
		child = memento.getChild(IImportExportConstants.IE_NODE_RESOURCE);
		map.put(IImportExportConstants.IE_NODE_PATH, child.getString(IImportExportConstants.IE_NODE_PATH));
		return map;
	}
	
	/**
	 * Collects the 'name' and 'value' key / attribute from the given memento and places it in the specified map
	 * @param memento the memento to read a name / value attribute from 
	 * @param map the map to add the read attribute to
	 */
	private void readAttribute(IMemento memento, Map<String, Object> map) {
		String name = memento.getString(IImportExportConstants.IE_NODE_NAME), 
		   	   value = memento.getString(IImportExportConstants.IE_NODE_VALUE);
		if (value != null && name != null) {
			if (name.equals(IInternalDebugUIConstants.WORKING_SET_NAME)) {
				fCurrentWorkingSetProperty = value;
			}
			Object val = value;
			try {
				val = Integer.valueOf(value);
			} catch (NumberFormatException e) {
				if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("true")) { //$NON-NLS-1$ //$NON-NLS-2$
					val = Boolean.valueOf(value);
				}
			}
			if(val != null) {
				map.put(name, val);
			}
		}
	}
	
	/**
	 * restores all of the attributes back into the given marker, recreates the breakpoint in the
	 * breakpoint manager, and optionally recreates any working set(s) the breakpoint belongs to.
	 * @param marker the marker to create the new breakpoint on
	 * @param attributes the attributes to set in the new breakpoint
	 * @param participants the list of participants used to verify the restored breakpoint
	 * @since 3.5
	 */
	protected void restoreBreakpoint(IMarker marker, final Map<String, Object> attributes, IBreakpointImportParticipant[] participants) {
		for (Entry<String, Object> entry : attributes.entrySet()) {
			try {
				marker.setAttribute(entry.getKey(), entry.getValue());
			} catch (CoreException ce) {
			}
		}
		IBreakpoint breakpoint = null;
		try {
			// create the breakpoint
			breakpoint = fManager.createBreakpoint(marker);
			breakpoint.setEnabled(((Boolean)attributes.get(IImportExportConstants.IE_BP_ENABLED)).booleanValue());
			breakpoint.setPersisted(((Boolean)attributes.get(IImportExportConstants.IE_BP_PERSISTANT)).booleanValue());
			breakpoint.setRegistered(((Boolean)attributes.get(IImportExportConstants.IE_BP_REGISTERED)).booleanValue());
			fAdded.add(breakpoint);
			if (fImportBreakpoints && fCreateWorkingSets && fCurrentWorkingSetProperty != null) {
				String[] names = fCurrentWorkingSetProperty.split("\\" + IImportExportConstants.DELIMITER); //$NON-NLS-1$
				updateWorkingSets(names, breakpoint);
			}
			if(participants != null) {
				for(int i = 0; i < participants.length; i++) {
					participants[i].verify(breakpoint);
				}
			}
		}
		catch(CoreException ce) {
			//Something bad happened while trying to restore the breakpoint, remove it from the cached list and delete the marker
			//to ensure the manager does not hold bogus breakpoints
			if(breakpoint != null) {
				try {
					fAdded.remove(breakpoint);
					marker.delete();
				} catch (CoreException e) {}
			}
		}
	}
	
	/**
	 * Updates the working sets the given breakpoint belongs to
	 * @param wsnames the array of working set names
	 * @param breakpoint the breakpoint to add to the working sets
	 * @since 3.5
	 */
	private void updateWorkingSets(String[] wsnames, IBreakpoint breakpoint) {
		IWorkingSetManager mgr = PlatformUI.getWorkbench().getWorkingSetManager();
		ArrayList<IWorkingSet> sets = new ArrayList<IWorkingSet>();
		collectContainingWorkingsets(breakpoint, sets);
		for (int i = 0; i < wsnames.length; i++) {
			if("".equals(wsnames[i])) { //$NON-NLS-1$
				continue;
			}
			IWorkingSet set = mgr.getWorkingSet(wsnames[i]);
			if(set == null) {
				//create working set
				set = mgr.createWorkingSet(wsnames[i], new IAdaptable[] {});
				set.setId(IDebugUIConstants.BREAKPOINT_WORKINGSET_ID);
				mgr.addWorkingSet(set);
			}
			if(!sets.contains(set)) {
				IAdaptable[] elements = set.getElements();
				IAdaptable[] newElements = new IAdaptable[elements.length + 1];
				newElements[newElements.length - 1] = breakpoint;
				System.arraycopy(elements, 0, newElements, 0, elements.length);
				set.setElements(newElements);
			}
			sets.remove(set);
		}
		ArrayList<IAdaptable> items = null;
		for (IWorkingSet set : sets) {
			items = new ArrayList<IAdaptable>(Arrays.asList(set.getElements()));
			if(items.remove(breakpoint)) {
				set.setElements(items.toArray(new IAdaptable[items.size()]));
			}
		}
	}
	
	/**
	 * Collects all of the breakpoint working sets that contain the given {@link IBreakpoint}
	 * in the given list
	 * 
	 * @param breakpoint the breakpoint to collect working set containers from 
	 * @param collector the list to collect containing working sets in 
	 * @since 3.5
	 */
	private void collectContainingWorkingsets(IBreakpoint breakpoint, List<IWorkingSet> collector) {
		IWorkingSetManager mgr = PlatformUI.getWorkbench().getWorkingSetManager();
		IWorkingSet[] sets = mgr.getWorkingSets();
		for (int i = 0; i < sets.length; i++) {
			if(IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(sets[i].getId()) &&
					containsBreakpoint(sets[i], breakpoint)) {
				collector.add(sets[i]);
			}
		}
	}
	
	/**
	 * Method to ensure markers and breakpoints are not both added to the working set
	 * @param set the set to check
	 * @param breakpoint the breakpoint to check for existence
	 * @return true if it is present false otherwise
	 */
	private boolean containsBreakpoint(IWorkingSet set, IBreakpoint breakpoint) {
		IAdaptable[] elements = set.getElements();
		for (int i = 0; i < elements.length; i++) {
			if (elements[i].equals(breakpoint)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Returns the breakpoints that were imported by this operation, possibly
	 * an empty list. 
	 * 
	 * @return breakpoints imported by this operation
	 * @since 3.5
	 */
	public IBreakpoint[] getImportedBreakpoints() {
		return fAdded.toArray(new IBreakpoint[fAdded.size()]);
	}
}
