/*******************************************************************************
 * Copyright (c) 2014, 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.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.IBreakpointListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension;
import org.eclipse.jdt.debug.testplugin.JavaTestPlugin;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.internal.debug.ui.LocalFileStorageEditorInput;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * Tests the Java debugger's 'toggle breakpoints target'.
 */
public abstract class AbstractToggleBreakpointsTarget extends AbstractDebugTest {
	
	class Listener implements IBreakpointListener {
		
		List<IBreakpoint> added = new ArrayList<IBreakpoint>();
		List<IBreakpoint> removed = new ArrayList<IBreakpoint>();

		@Override
		public void breakpointAdded(IBreakpoint breakpoint) {
			synchronized (added) {
				added.add(breakpoint);
				added.notifyAll();
			}
		}

		@Override
		public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
			synchronized (removed) {
				removed.add(breakpoint);
				removed.notifyAll();
			}
		}

		@Override
		public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
		}
		
		public IBreakpoint getAdded() throws Exception {
			synchronized (added) {
				if (added.isEmpty()) {
					added.wait(DEFAULT_TIMEOUT);
				}
			}
			assertFalse("Breakpoint not added", added.isEmpty());
			return added.get(0);
		}
		
		public boolean isEmpty() throws Exception{
			synchronized (added) {
				if (added.isEmpty()) {
					added.wait(DEFAULT_TIMEOUT);
					return true;
				}
			}
			return false;

		}
		
		public IBreakpoint getRemoved() throws Exception {
			synchronized (removed) {
				if (removed.isEmpty()) {
					removed.wait(DEFAULT_TIMEOUT);
				}
			}
			assertFalse("Breakpoint not removed", removed.isEmpty());
			return removed.get(0);
		}
		
		
	}

	public AbstractToggleBreakpointsTarget(String name) {
		super(name);
	}
	
		
	/**
	 * Opens an editor on the given external file and toggles a breakpoint.
	 * 
	 * @param externalFile path to external file in the test plug-in
	 * @param line line number (1 based)
	 * @throws Exception on failure
	 */
	protected void toggleBreakpoint(final IPath externalFile, final int line) throws Exception {
		final Exception[] exs = new Exception[1];
		DebugUIPlugin.getStandardDisplay().syncExec(new Runnable() {
			@Override
			public void run() {
				try {
					File file = JavaTestPlugin.getDefault().getFileInPlugin(externalFile);
					LocalFileStorage storage = new LocalFileStorage(file);
					IEditorPart editor = DebugUIPlugin.getActiveWorkbenchWindow().getActivePage().openEditor(new LocalFileStorageEditorInput(storage), JavaUI.ID_CU_EDITOR);
					ITextEditor textEditor = (ITextEditor) editor;
			        IEditorInput editorInput = textEditor.getEditorInput();
			        IDocumentProvider documentProvider = textEditor.getDocumentProvider();
			        IDocument document = documentProvider.getDocument(editorInput);
			        int offset = document.getLineOffset(line);
			        IToggleBreakpointsTargetExtension toggle = (IToggleBreakpointsTargetExtension) editor.getAdapter(IToggleBreakpointsTarget.class);
			        toggle.toggleBreakpoints(editor, new TextSelection(document, offset, 0));
				} catch (Exception e) {
					exs[0] = e;
				}
			}
		});
		if (exs[0] != null) {
			throw exs[0];
		}
	}

}
