/*******************************************************************************
 * Copyright (c) 2010, 2011 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.wst.jsdt.debug.internal.core.breakpoints;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
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.Path;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.Breakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint;
import org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.BreakpointEvent;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.Event;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.EventSet;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.ScriptLoadEvent;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.BreakpointRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.EventRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ScriptLoadRequest;
import org.eclipse.wst.jsdt.debug.core.model.JavaScriptDebugModel;
import org.eclipse.wst.jsdt.debug.internal.core.Constants;
import org.eclipse.wst.jsdt.debug.internal.core.JavaScriptDebugPlugin;
import org.eclipse.wst.jsdt.debug.internal.core.Messages;
import org.eclipse.wst.jsdt.debug.internal.core.launching.SourceLookup;
import org.eclipse.wst.jsdt.debug.internal.core.model.IJavaScriptEventListener;
import org.eclipse.wst.jsdt.debug.internal.core.model.JavaScriptDebugTarget;
import org.eclipse.wst.jsdt.debug.internal.core.model.JavaScriptThread;
import org.eclipse.wst.jsdt.debug.internal.core.model.Script;

/**
 * Abstract representation of a JSDI breakpoint
 * 
 * @since 1.0
 */
public abstract class JavaScriptBreakpoint extends Breakpoint implements IJavaScriptBreakpoint, IJavaScriptEventListener {

	/**
	 * The total count of all of the targets this breakpoint is installed in
	 */
	public static final String INSTALL_COUNT = JavaScriptDebugPlugin.PLUGIN_ID + ".install_count"; //$NON-NLS-1$

	private HashSet targets = null;
	private HashMap requestspertarget = new HashMap(4);

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.Breakpoint#setMarker(org.eclipse.core.resources.IMarker)
	 */
	public void setMarker(IMarker marker) throws CoreException {
		super.setMarker(marker);
		// reset the install count
		setAttribute(INSTALL_COUNT, 0);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.Breakpoint#setAttribute(java.lang.String, boolean)
	 */
	protected void setAttribute(final String attributeName, final boolean value) throws CoreException {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				ensureMarker().setAttribute(attributeName, value);
			}
		};
		workspace.run(runnable, getMarkerRule(), IWorkspace.AVOID_UPDATE, null);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.Breakpoint#setAttribute(java.lang.String, java.lang.Object)
	 */
	protected void setAttribute(final String attributeName, final Object value) throws CoreException {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				ensureMarker().setAttribute(attributeName, value);
			}
		};
		workspace.run(runnable, getMarkerRule(), IWorkspace.AVOID_UPDATE, null);
	}
	
	/**
	 * Add this breakpoint to the breakpoint manager, or sets it as unregistered.
	 */
	protected void register(boolean register) throws CoreException {
		DebugPlugin plugin = DebugPlugin.getDefault();
		if (plugin != null && register) {
			plugin.getBreakpointManager().addBreakpoint(this);
		} else {
			setRegistered(false);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier()
	 */
	public String getModelIdentifier() {
		return JavaScriptDebugModel.MODEL_ID;
	}

	/**
	 * Returns whether this breakpoint should be "skipped". Breakpoints are skipped if the breakpoint manager is disabled and the breakpoint is registered with the manager
	 * 
	 * @return whether this breakpoint should be skipped
	 */
	public boolean shouldSkipBreakpoint() throws CoreException {
		DebugPlugin plugin = DebugPlugin.getDefault();
		return plugin != null && isRegistered() && !plugin.getBreakpointManager().isEnabled();
	}
	
	/**
	 * Adds the given debug target to the listing of targets that this breakpoint cares about
	 * 
	 * @param target
	 * @throws CoreException
	 */
	public void addToTarget(JavaScriptDebugTarget target) throws CoreException {
		if (target.isTerminated() || shouldSkipBreakpoint()) {
			return;
		}
		// Add script load handler
		ScriptLoadRequest request = target.getEventRequestManager().createScriptLoadRequest();
		request.setEnabled(isEnabled());
		registerRequest(target, request);

		// Add to all loaded scripts
		String scriptPath = getScriptPath();
		if (scriptPath == null) {
			return;
		}
		
		try {
			if(JavaScriptDebugPlugin.isExternalSource(new Path(scriptPath))) {
				scriptPath = getMarker().getResource().getPersistentProperty(SourceLookup.SCRIPT_URL);
			}
			if(scriptPath == null) {
				return;
			}
			List/* ScriptReference */scripts = target.underlyingScripts(Script.resolveName(URIUtil.fromString(scriptPath)));
			boolean success = true;
			for (Iterator iter = scripts.iterator(); iter.hasNext();) {
				ScriptReference script = (ScriptReference) iter.next();
				if (scriptPathMatches(script))
					success &= createRequest(target, script);
			}
			if (success) {
				if (this.targets == null) {
					this.targets = new HashSet();
				}
				this.targets.add(target);
			}
		}
		catch(URISyntaxException urise) {
			JavaScriptDebugPlugin.log(urise);
		}
	}

	/**
	 * Creates a request for the given script in the given target
	 * 
	 * @param target
	 *            the target to register with
	 * @param script
	 *            the script we want to set the breakpoint in
	 * @return true if a new request was created false otherwise
	 * @throws CoreException
	 */
	protected abstract boolean createRequest(JavaScriptDebugTarget target, ScriptReference script) throws CoreException;

	/**
	 * Configures the request with attributes from the breakpoint
	 * 
	 * @param request
	 * @throws CoreException
	 */
	protected void configureRequest(BreakpointRequest request) throws CoreException {
		request.addHitCountFilter(getHitCount());
	}

	/**
	 * Removes the given debug target from the listing of targets this breakpoint cares about
	 * 
	 * @param target
	 */
	public void removeFromTarget(JavaScriptDebugTarget target) {
		List requests = getRequests(target);
		if (requests != null) {
			for (Iterator iter = requests.iterator(); iter.hasNext();) {
				EventRequest request = null;
				try {
					request = (EventRequest) iter.next();
					if (target.isAvailable()) {
						target.getEventRequestManager().deleteEventRequest(request);
					}
				} finally {
					deregisterRequest(target, request);
				}
			}
		}
		synchronized (this.requestspertarget) {
			this.requestspertarget.remove(target);
		}
		if (this.targets == null) {
			return;
		}
		this.targets.remove(target);
	}

	/**
	 * Recreate this breakpoint in all targets
	 * 
	 * @throws CoreException
	 */
	protected void recreateBreakpoint() throws CoreException {
		DebugPlugin plugin = DebugPlugin.getDefault();
		if (plugin != null) {
			IDebugTarget[] targets = plugin.getLaunchManager().getDebugTargets();
			for (int i = 0; i < targets.length; i++) {
				if (targets[i].getModelIdentifier().equals(JavaScriptDebugModel.MODEL_ID)) {
					recreateBreakpointFor((JavaScriptDebugTarget) targets[i]);
				}
			}
		}
	}

	/**
	 * Recreates this breakpoint in the given debug target
	 * 
	 * @param target
	 * @throws CoreException
	 */
	void recreateBreakpointFor(JavaScriptDebugTarget target) throws CoreException {
		if (target.isAvailable() && target.getBreakpoints().contains(this)) {
			removeFromTarget(target);
			addToTarget(target);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.Breakpoint#setEnabled(boolean)
	 */
	public void setEnabled(boolean enabled) throws CoreException {
		if(isEnabled() != enabled) {
			setAttribute(ENABLED, enabled);
			recreateBreakpoint();
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint#setSuspendPolicy(int)
	 */
	public void setSuspendPolicy(int policy) throws CoreException {
		if(getSuspendPolicy() != policy) {
			setAttribute(SUSPEND_POLICY, policy);
			recreateBreakpoint();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint#getSuspendPolicy()
	 */
	public int getSuspendPolicy() throws CoreException {
		return ensureMarker().getAttribute(SUSPEND_POLICY, SUSPEND_THREAD);
	}

	/**
	 * Returns if this breakpoint is currently installed in any targets
	 * 
	 * @return true if this breakpoint is installed in any targets, false otherwise
	 * @throws CoreException
	 */
	public boolean isInstalled() throws CoreException {
		return ensureMarker().getAttribute(INSTALL_COUNT, 0) > 0;
	}

	/**
	 * Increments the install count of this breakpoint
	 */
	protected void incrementInstallCount() throws CoreException {
		int count = getInstallCount();
		setAttribute(INSTALL_COUNT, count + 1);
	}

	/**
	 * Returns the <code>INSTALL_COUNT</code> attribute of this breakpoint or 0 if the attribute is not set.
	 */
	public int getInstallCount() throws CoreException {
		return ensureMarker().getAttribute(INSTALL_COUNT, 0);
	}

	/**
	 * Decrements the install count of this breakpoint.
	 */
	protected void decrementInstallCount() throws CoreException {
		int count = getInstallCount();
		if (count > 0) {
			setAttribute(INSTALL_COUNT, count - 1);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint#setHitCount(int)
	 */
	public void setHitCount(int count) throws CoreException, IllegalArgumentException {
		if (count != getHitCount()) {
			setAttribute(HIT_COUNT, count);
			recreateBreakpoint();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint#getHitCount()
	 */
	public int getHitCount() throws CoreException {
		return ensureMarker().getAttribute(HIT_COUNT, -1);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint#getScriptPath()
	 */
	public String getScriptPath() throws CoreException {
		return ensureMarker().getAttribute(SCRIPT_PATH, Constants.EMPTY_STRING);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint#getTypeName()
	 */
	public String getTypeName() throws CoreException {
		return ensureMarker().getAttribute(TYPE_NAME, null);
	}

	/**
	 * Registers the given request for this breakpoint for the given target
	 * 
	 * @param target
	 * @param request
	 */
	protected void registerRequest(JavaScriptDebugTarget target, EventRequest request) {
		addRequestForTarget(target, request);
		if (!(request instanceof ScriptLoadRequest)) {
			try {
				incrementInstallCount();
			} catch (CoreException ce) {
				JavaScriptDebugPlugin.log(ce);
			}
		}
	}

	/**
	 * Adds the given request to the list of requests for the given target
	 * @param target
	 * @param request
	 */
	protected synchronized void addRequestForTarget(JavaScriptDebugTarget target, EventRequest request) {
		ArrayList requests = getRequests(target);
		if (requests == null) {
			synchronized (this.requestspertarget) {
				requests = new ArrayList(2);
				this.requestspertarget.put(target, requests);
			}
		}
		requests.add(request);
		target.addJSDIEventListener(this, request);
	}

	/**
	 * Returns any existing requests associated with the given target
	 * 
	 * @param target
	 * @return list of requests for the given target
	 */
	protected ArrayList getRequests(JavaScriptDebugTarget target) {
		ArrayList list = null;
		synchronized (this.requestspertarget) {
			list = (ArrayList) this.requestspertarget.get(target);
		}
		return list;
	}

	/**
	 * Remove this breakpoint as an event listener
	 * 
	 * @param target
	 * @param request
	 */
	protected void deregisterRequest(JavaScriptDebugTarget target, EventRequest request) {
		target.removeJSDIEventListener(this, request);
		if (!(request instanceof ScriptLoadRequest)) {
			try {
				decrementInstallCount();
			} catch (CoreException ce) {
				JavaScriptDebugPlugin.log(ce);
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.internal.core.model.IJavaScriptEventListener#handleEvent(org.eclipse.wst.jsdt.debug.core.jsdi.event.Event, org.eclipse.wst.jsdt.debug.internal.core.model.JavaScriptDebugTarget, boolean, org.eclipse.wst.jsdt.debug.core.jsdi.event.EventSet)
	 */
	public boolean handleEvent(Event event, JavaScriptDebugTarget target, boolean suspendVote, EventSet eventSet) {
		// get the thread and suspend it
		if (event instanceof BreakpointEvent) {
			JavaScriptThread thread = target.findThread(((BreakpointEvent) event).thread());
			if (thread != null) {
				return !thread.suspendForBreakpoint(this, suspendVote);
			}
		}
		if (event instanceof ScriptLoadEvent) {
			ScriptLoadEvent sevent = (ScriptLoadEvent) event;
			ScriptReference script = sevent.script();
			
			try {
				if (scriptPathMatches(script)) 
					createRequest(target, script);
			} catch (CoreException ce) {
				JavaScriptDebugPlugin.log(ce);
			}
		}
		return true;
	}

	protected boolean scriptPathMatches(ScriptReference script) throws CoreException {
		URI sourceURI = script.sourceURI();
		if ("file".equals(sourceURI.getScheme())) {//$NON-NLS-1$			
			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
			URI workspaceURI = workspaceRoot.getRawLocationURI();			
			sourceURI = workspaceURI.relativize(sourceURI);
		}
		String path = getScriptPath();
		IPath spath = new Path(path);
		if(spath.segment(0).equals(Messages.external_javascript_source)) {
			spath = spath.removeFirstSegments(1).makeAbsolute();
		}
		//XXX use the same algorithm we use to save the source to 'encode' the source URI for comparison
		IPath uripath = SourceLookup.getSourcePath(sourceURI);
		if(uripath != null) {
			uripath = uripath.makeAbsolute();
		}
		return spath.equals(uripath);
	}

	/**
	 * Returns if the type names for the breakpoint are equal or not. Two <code>null</code> type names are considered to be equal.
	 * 
	 * @param tname1
	 * @param tname2
	 * @return true if the type names are equal, false otherwise
	 */
	boolean typeNamesEqual(String tname1, String tname2) {
		if (tname1 == null && tname2 == null) {
			return true;
		}
		return tname1 != null && tname1.equals(tname2);
	}

	/**
	 * Custom comparison to avoid the leading separator issue from saying the paths are not equal
	 * 
	 * @param p1
	 * @param p2
	 * @return
	 */
	boolean pathsEqual(IPath p1, IPath p2) {
		if (p1.segmentCount() == p2.segmentCount()) {
			String[] segments = p1.segments();
			for (int i = 0; i < segments.length; i++) {
				if (!segments[i].equals(p2.segment(i))) {
					return false;
				}
			}
		}
		return true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.internal.core.model.IJavaScriptEventListener#eventSetComplete(org.eclipse.wst.jsdt.debug.core.jsdi.event.Event, org.eclipse.wst.jsdt.debug.internal.core.model.JavaScriptDebugTarget, boolean, org.eclipse.wst.jsdt.debug.core.jsdi.event.EventSet)
	 */
	public void eventSetComplete(Event event, JavaScriptDebugTarget target, boolean suspend, EventSet eventSet) {
		if (event instanceof BreakpointEvent) {
			JavaScriptThread thread = target.findThread(((BreakpointEvent) event).thread());
			if (thread != null) {
				thread.suspendForBreakpointComplete(this, suspend, eventSet);
			}
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint#setJavaScriptElementHandle(java.lang.String)
	 */
	public void setJavaScriptElementHandle(String handle) throws CoreException {
		ensureMarker().setAttribute(ELEMENT_HANDLE, handle);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint#getJavaScriptElementHandle()
	 */
	public String getJavaScriptElementHandle() throws CoreException {
		return ensureMarker().getAttribute(ELEMENT_HANDLE, null);
	}
}
