/*******************************************************************************
 * Copyright (c) 2005, 2018 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
 *     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.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
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;

/**
 * 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<>();

	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;
	}

	@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), StandardCharsets.UTF_8)) {
					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 (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 (IMemento node : nodes) {
				if(localmonitor.isCanceled()) {
					return;
				}
				attributes = collectBreakpointProperties(node);
				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 (IBreakpoint bp : bps) {
			for (IBreakpointImportParticipant participant : participants) {
				try {
					if (participant.matches(attributes, bp)) {
						return bp.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<>();

		//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 (IMemento c : children) {
			readAttribute(c, 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 (IBreakpointImportParticipant participant : participants) {
					participant.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<>();
		collectContainingWorkingsets(breakpoint, sets);
		for (String wsname : wsnames) {
			if ("".equals(wsname)) { //$NON-NLS-1$
				continue;
			}
			IWorkingSet set = mgr.getWorkingSet(wsname);
			if (set == null) {
				//create working set
				set = mgr.createWorkingSet(wsname, 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<>(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 (IWorkingSet set : sets) {
			if (IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(set.getId()) && containsBreakpoint(set, breakpoint)) {
				collector.add(set);
			}
		}
	}

	/**
	 * 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 (IAdaptable element : elements) {
			if (element.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()]);
	}
}
