/*******************************************************************************
 *  Copyright (c) 2000, 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
 *******************************************************************************/
package org.eclipse.jdt.debug.tests.breakpoints;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.IBreakpointListener;
import org.eclipse.debug.core.IBreakpointsListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;

/**
 * Tests breakpoint creation/deletion and listener interfaces.
 */
public class BreakpointListenerTests extends AbstractDebugTest implements IBreakpointListener, IBreakpointsListener {

	/**
	 * the number of add callbacks
	 */
	public int fAddCallbacks = 0;
	/**
	 * the running total
	 */
	public int fTotalAdded = 0;
	/**
	 * the number of remove callbacks
	 */
	public int fRemoveCallbacks = 0;
	/**
	 * the total removed
	 */
	public int fTotalRemoved = 0;
	/**
	 * the number of change callbacks
	 */
	public int fChangeCallabcks = 0;
	/**
	 * the total changed
	 */
	public int fTotalChanged = 0;

	/**
	 * Constructor
	 * @param name
	 */
	public BreakpointListenerTests(String name) {
		super(name);
	}

	protected void resetCallbacks() {
		waitForBuild();
		fAddCallbacks = 0;
		fTotalAdded = 0;

		fRemoveCallbacks = 0;
		fTotalRemoved = 0;

		fChangeCallabcks = 0;
		fTotalChanged = 0;
	}
	/**
	 * Creates sample breakpoints
	 *
	 * @return List
	 */
	protected List<IJavaLineBreakpoint> createBreakpoints(String typeName) throws Exception {
		List<IJavaLineBreakpoint> bps = new ArrayList<IJavaLineBreakpoint>();
		// anonymous class
		bps.add(createUnregisteredLineBreakpoint(43, typeName));
		// blocks
		bps.add(createUnregisteredLineBreakpoint(102, typeName));
		// constructor
		bps.add(createUnregisteredLineBreakpoint(77, typeName));
		// else
		bps.add(createUnregisteredLineBreakpoint(88, typeName));
		//finally after catch
		bps.add(createUnregisteredLineBreakpoint(120, typeName));
		//finally after try
		bps.add(createUnregisteredLineBreakpoint(128, typeName));
		// for loop
		bps.add(createUnregisteredLineBreakpoint(93, typeName));
		// if
		bps.add(createUnregisteredLineBreakpoint(81, typeName));
		// initializer
		bps.add(createUnregisteredLineBreakpoint(17, typeName));
		// inner class
		bps.add(createUnregisteredLineBreakpoint(22, typeName));
		// return true
		bps.add(createUnregisteredLineBreakpoint(72, typeName));
		// instance method
		bps.add(createUnregisteredLineBreakpoint(107, typeName));
		// static method
		bps.add(createUnregisteredLineBreakpoint(53, typeName));
		// case statement
		bps.add(createUnregisteredLineBreakpoint(133, typeName));
		// default statement
		bps.add(createUnregisteredLineBreakpoint(140, typeName));
		// synchronized blocks
		bps.add(createUnregisteredLineBreakpoint(146, typeName));
		// try
		bps.add(createUnregisteredLineBreakpoint(125, typeName));
		//catch
		bps.add(createUnregisteredLineBreakpoint(118, typeName));
		// while
		bps.add(createUnregisteredLineBreakpoint(97, typeName));

		return bps;
	}

	/**
	 * Tests a single breakpoint listener
	 * @throws Exception
	 */
	public void testSingleListener() throws Exception {
		List<IJavaLineBreakpoint> bps = createBreakpoints("Breakpoints");

		try {
			getBreakpointManager().addBreakpointListener((IBreakpointListener)this);

			resetCallbacks();
			getBreakpointManager().addBreakpoints(bps.toArray(new IBreakpoint[bps.size()]));
			assertEquals("Should have received individual add notifications", bps.size(), fAddCallbacks);
			assertEquals("Number of breakpoints added incorrect", bps.size(), fTotalAdded);
			//assertEquals("Should be change callbacks for IMarker.MESSAGE updates", bps.size(), fChangeCallabcks);
			assertEquals("Should be no removes", 0, fRemoveCallbacks);

			resetCallbacks();
			getBreakpointManager().removeBreakpoints(bps.toArray(new IBreakpoint[bps.size()]), true);
			assertEquals("Should have received individual remove notifications", bps.size(), fRemoveCallbacks);
			assertEquals("Should of breakpoints removed incorrect", bps.size(), fTotalRemoved);
			assertEquals("Should be no changes", 0, fChangeCallabcks);
			assertEquals("Should be no additions", 0, fAddCallbacks);

		} finally {
			getBreakpointManager().removeBreakpointListener((IBreakpointListener)this);
			removeAllBreakpoints();
		}

	}

	/**
	 * Tests more than one simultaneous breakpoint listener
	 * @throws Exception
	 */
	public void testMultiListener() throws Exception {
		List<IJavaLineBreakpoint> bps = createBreakpoints("Breakpoints");

		try {
			getBreakpointManager().addBreakpointListener((IBreakpointsListener)this);

			resetCallbacks();
			getBreakpointManager().addBreakpoints(bps.toArray(new IBreakpoint[bps.size()]));
			assertEquals("Should have received one add notification", 1, fAddCallbacks);
			assertEquals("Number of breakpoints added incorrect", bps.size(), fTotalAdded);
			//assertEquals("Should be 1 change for IMarker.MESSAGE update", 1, fChangeCallabcks);
			assertEquals("Should be no removes", 0, fRemoveCallbacks);

			resetCallbacks();
			getBreakpointManager().removeBreakpoints(bps.toArray(new IBreakpoint[bps.size()]), true);
			assertEquals("Should have received one remove notification", 1, fRemoveCallbacks);
			assertEquals("Should of breakpoints removed incorrect", bps.size(), fTotalRemoved);
			assertEquals("Should be no changes", 0, fChangeCallabcks);
			assertEquals("Should be no additions", 0, fAddCallbacks);

		} finally {
			getBreakpointManager().removeBreakpointListener((IBreakpointsListener)this);
			removeAllBreakpoints();
		}

	}

	/**
	 * Test multiple breakpoint listeners over a project open and close
	 * @throws Exception
	 */
	public void testMultiListenerProjectCloseOpen() throws Exception {
		List<IJavaLineBreakpoint> bps = createBreakpoints("Breakpoints");

		try {
			// close all editors before closing project: @see bug 204023
			closeAllEditors();

			getBreakpointManager().addBreakpointListener((IBreakpointsListener)this);

			resetCallbacks();
			getBreakpointManager().addBreakpoints(bps.toArray(new IBreakpoint[bps.size()]));
			assertEquals("Should have received one add notification", 1, fAddCallbacks);
			assertEquals("Number of breakpoints added incorrect", bps.size(), fTotalAdded);
			//assertEquals("Should be 1 change for IMarker.MESSAGE update", 1, fChangeCallabcks);
			assertEquals("Should be no removes", 0, fRemoveCallbacks);

			resetCallbacks();
			get14Project().getProject().close(null);
			waitForBuild();
			assertEquals("Should have received one remove notification", 1, fRemoveCallbacks);
			assertEquals("Should of breakpoints removed incorrect", bps.size(), fTotalRemoved);
			assertEquals("Should be no changes", 0, fChangeCallabcks);
			assertEquals("Should be no additions", 0, fAddCallbacks);

			resetCallbacks();
			get14Project().getProject().open(null);
			waitForBuild();
			assertEquals("Should have received one add notification", 1, fAddCallbacks);
			assertEquals("Number of breakpoints added incorrect", bps.size(), fTotalAdded);
			assertEquals("Should be no changes", 0, fChangeCallabcks);
			assertEquals("Should be no removes", 0, fRemoveCallbacks);

		} finally {
			get14Project().getProject().open(null);
			getBreakpointManager().removeBreakpointListener((IBreakpointsListener)this);
			removeAllBreakpoints();
		}

	}

	/**
	 * Tests multiple breakpoint listeners over a compilation move operation
	 * @throws Exception
	 */
	public void testMultiListenerMoveCompilationUnit() throws Exception {
		IJavaProject project = get14Project();
		ICompilationUnit cu = (ICompilationUnit)project.findElement(new Path("Breakpoints.java"));
		assertNotNull("Did not find compilation unit", cu);
		cu.copy(cu.getParent(), null, "BreakpointsCopyA.java", false, null);
		waitForBuild();
		List<IJavaLineBreakpoint> bps = createBreakpoints("BreakpointsCopyA");
		cu = (ICompilationUnit)project.findElement(new Path("BreakpointsCopyA.java"));
		assertNotNull("Did not find compilation unit copy", cu);

		try {
			getBreakpointManager().addBreakpointListener((IBreakpointsListener)this);

			resetCallbacks();
			getBreakpointManager().addBreakpoints(bps.toArray(new IBreakpoint[bps.size()]));
			waitForBuild();
			assertEquals("Should have received one add notification", 1, fAddCallbacks);
			assertEquals("Number of breakpoints added incorrect", bps.size(), fTotalAdded);
			//assertEquals("Should be 1 change callback for IMarker.MESSAGE update", 1, fChangeCallabcks);
			assertEquals("Should be no removes", 0, fRemoveCallbacks);

			resetCallbacks();
			cu.rename("BreakpointsCopyTwoA.java", false, null);
			waitForBuild();
			assertEquals("Should have received one remove notification", 1, fRemoveCallbacks);
			assertEquals("Number of breakpoints removed incorrect", bps.size(), fTotalRemoved);
			assertEquals("Should be no changes", 0, fChangeCallabcks);
			assertEquals("Should be no additions", 0, fAddCallbacks);

			cu = (ICompilationUnit)project.findElement(new Path("BreakpointsCopyTwoA.java"));
			assertNotNull("Did not find CU", cu);
			cu.delete(false, null);
			waitForBuild();

		} finally {
			getBreakpointManager().removeBreakpointListener((IBreakpointsListener)this);
			removeAllBreakpoints();
		}

	}

	/**
	 * Tests a single breakpoint listener over the move of a compilation unit
	 * @throws Exception
	 */
	public void testSingleListenerMoveCompilationUnit() throws Exception {
		IJavaProject project = get14Project();
		ICompilationUnit cu = (ICompilationUnit)project.findElement(new Path("Breakpoints.java"));
		assertNotNull("Did not find compilation unit", cu);
		cu.copy(cu.getParent(), null, "BreakpointsCopy.java", false, null);
		waitForBuild();
		List<IJavaLineBreakpoint> bps = createBreakpoints("BreakpointsCopy");
		cu = (ICompilationUnit)project.findElement(new Path("BreakpointsCopy.java"));
		assertNotNull("Did not find compilation unit copy", cu);

		try {
			getBreakpointManager().addBreakpointListener((IBreakpointListener)this);

			resetCallbacks();
			getBreakpointManager().addBreakpoints(bps.toArray(new IBreakpoint[bps.size()]));
			waitForBuild();
			assertEquals("Should have received one add notification", bps.size(), fAddCallbacks);
			assertEquals("Number of breakpoints added incorrect", bps.size(), fTotalAdded);
			//assertEquals("Should be no changes", 0, fChangeCallabcks);
			assertEquals("Should be no removes", 0, fRemoveCallbacks);

			resetCallbacks();
			cu.rename("BreakpointsCopyTwo.java", false, null);
			waitForBuild();
			assertEquals("Incorrect number of remove notifications", bps.size(), fRemoveCallbacks);
			assertEquals("Incorrect number of breakpoints removed", bps.size(), fTotalRemoved);
			assertEquals("Should be no changes", 0, fChangeCallabcks);
			assertEquals("Should be no additions", 0, fAddCallbacks);

			cu = (ICompilationUnit)project.findElement(new Path("BreakpointsCopyTwo.java"));
			assertNotNull("Did not find CU", cu);
			cu.delete(false, null);
			waitForBuild();

		} finally {
			getBreakpointManager().removeBreakpointListener((IBreakpointListener)this);
			removeAllBreakpoints();
		}

	}

	/**
	 * Creates and returns a line breakpoint at the given line number in the type with the
	 * given name, that is <b>not</b> registered with the breakpoint manager.
	 *
	 * @param lineNumber line number
	 * @param typeName type name
	 */
	protected IJavaLineBreakpoint createUnregisteredLineBreakpoint(int lineNumber, String typeName) throws Exception {
		return JDIDebugModel.createLineBreakpoint(getBreakpointResource(typeName), typeName, lineNumber, -1, -1, 0, false, null);
	}

	/**
	 * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
	 */
	@Override
	public void breakpointAdded(IBreakpoint breakpoint) {
		fAddCallbacks++;
		fTotalAdded++;
	}

	/**
	 * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
	 */
	@Override
	public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
		fChangeCallabcks++;
		fTotalChanged++;
	}

	/**
	 * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
	 */
	@Override
	public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
		fRemoveCallbacks++;
		fTotalRemoved++;
	}

	/**
	 * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[])
	 */
	@Override
	public void breakpointsAdded(IBreakpoint[] breakpoints) {
		fAddCallbacks++;
		fTotalAdded += breakpoints.length;
	}

	/**
	 * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsChanged(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
	 */
	@Override
	public void breakpointsChanged(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
		fChangeCallabcks++;
		fTotalChanged += breakpoints.length;
	}

	/**
	 * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsRemoved(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
	 */
	@Override
	public void breakpointsRemoved(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
		fRemoveCallbacks++;
		fTotalRemoved += breakpoints.length;
	}
}
