/*******************************************************************************
 * Copyright (c) 2000, 2005 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.ui;

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

import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener3;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

/**
 * Tests view management.
 */
public class ViewMangementTests extends AbstractDebugTest implements IPerspectiveListener3 {

	// view ids
	public static final String VIEW_TWO = "org.eclipse.jdt.debug.tests.context.view.two";
	public static final String VIEW_ONE = "org.eclipse.jdt.debug.tests.context.view.one";

	private Object fEventLock = new Object();
	
	/**
	 * List of view ids expecting to open.
	 */
	private List fExpectingOpenEvents = new ArrayList();
	
	/**
	 * List of view ids expecting to close.
	 */
	private List fExpectingCloseEvents = new ArrayList();	
	
	// prefs to restore
	private String switch_on_launch;
	private String switch_on_suspend;
	private String debug_perspectives;
	
	public ViewMangementTests(String name) {
		super(name);
	}
		
	/**
	 * Switches to the specified perspective in the given window, and resets the perspective.
	 * 
	 * @param window
	 * @param perspectiveId
	 */
	protected void switchPerspective(IWorkbenchWindow window, String perspectiveId) {
		IPerspectiveDescriptor descriptor = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(perspectiveId);
		assertNotNull("missing perspective " + perspectiveId, descriptor);
		IWorkbenchPage page = window.getActivePage();
		page.setPerspective(descriptor);
		page.resetPerspective();
	}
	
	/**
	 * Siwtches to and resets the specified perspective in the active workbench window.
	 * 
	 * @return the window in which the perspective is ready
	 */
	private IWorkbenchWindow resetPerspective(final String id) {
		final IWorkbenchWindow[] windows = new IWorkbenchWindow[1];
		Runnable r = new Runnable() {
			public void run() {
				IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
				switchPerspective(window, id);
				windows[0] = window;
			}
		};
		sync(r);
		return windows[0];
	}
	
	/**
	 * Siwtches to and resets the debug perspective in the active workbench window.
	 * 
	 * @return the window in which the perspective is ready
	 */
	protected IWorkbenchWindow resetDebugPerspective() {
		return resetPerspective(IDebugUIConstants.ID_DEBUG_PERSPECTIVE);
	}
	
	/**
	 * Siwtches to and resets the java perspective in the active workbench window.
	 * 
	 * @return the window in which the perspective is ready
	 */
	protected IWorkbenchWindow resetJavaPerspective() {
		return resetPerspective(JavaUI.ID_PERSPECTIVE); 
	}	
	
	/**
	 * Sync exec the given runnable
	 * 
	 * @param r
	 */
	protected void sync(Runnable r) {
		DebugUIPlugin.getStandardDisplay().syncExec(r);
	}
	
	/**
	 * Returns whether the specified view is open
	 * 
	 * @param window
	 * @param id
	 * @return
	 */
	protected boolean isViewOpen(final IWorkbenchWindow window, final String id) {
		final IViewReference[] refs = new IViewReference[1];
		Runnable r = new Runnable() {
			public void run() {
				refs[0] = window.getActivePage().findViewReference(id);
			}
		};
		sync(r);
		return refs[0] != null;
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();
		IPreferenceStore preferenceStore = DebugUITools.getPreferenceStore();
		switch_on_launch = preferenceStore.getString(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE);
		switch_on_suspend = preferenceStore.getString(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND);
		debug_perspectives = preferenceStore.getString(IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES);
		preferenceStore.setValue(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND, MessageDialogWithToggle.NEVER);
		preferenceStore.setValue(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE, MessageDialogWithToggle.NEVER);
		preferenceStore.setValue(IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES, IDebugUIConstants.ID_DEBUG_PERSPECTIVE + "," + 
				JavaUI.ID_PERSPECTIVE + ",");
		fExpectingOpenEvents.clear();
		fExpectingCloseEvents.clear();
	}
	
	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		super.tearDown();
		IPreferenceStore preferenceStore = DebugUITools.getPreferenceStore();
		preferenceStore.setValue(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND, switch_on_suspend);
		preferenceStore.setValue(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE, switch_on_launch);
		preferenceStore.setValue(IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES, debug_perspectives);
	}

	/**
	 * Tests that context views auto-open in debug perspective.
	 * Both context views should auto-open.
	 * 
	 * @throws Exception
	 */
	public void testAutoOpenDebugPerspective() throws Exception {
		String typeName = "Breakpoints";
		// first line in main
		createLineBreakpoint(52, typeName);
		
		IJavaThread thread= null;
		IWorkbenchWindow window = null;
		try {
			window = resetDebugPerspective();
			synchronized (fEventLock) {
				expectingViewOpenEvents(window, new String[]{VIEW_ONE, VIEW_TWO});
				thread= launchToBreakpoint(typeName);
				fEventLock.wait(DEFAULT_TIMEOUT);
			}
			assertNotNull("Breakpoint not hit within timeout period", thread);
			assertTrue(buildRemainingEventsMessage(), checkComplete());
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
			window.removePerspectiveListener(this);
		}		
	}
	
	/**
	 * Tests that context views auto-open in debug perspective, and auto close on termination.
	 * View "two" should auto-close.
	 * 
	 * @throws Exception
	 */
	public void testAutoCloseDebugPerspective() throws Exception {
		String typeName = "Breakpoints";
		// first line in main
		createLineBreakpoint(52, typeName);
		
		IJavaThread thread= null;
		IWorkbenchWindow window = null;
		try {
			window = resetDebugPerspective();
			synchronized (fEventLock) {
				expectingViewOpenEvents(window, new String[]{VIEW_ONE, VIEW_TWO});
				thread= launchToBreakpoint(typeName);
				fEventLock.wait(DEFAULT_TIMEOUT);
			}
			assertNotNull("Breakpoint not hit within timeout period", thread);
			assertTrue(buildRemainingEventsMessage(), checkComplete());
			// terminate to auto close
			synchronized (fEventLock) {
				expectingViewCloseEvents(window, new String[]{VIEW_TWO});
				thread.terminate();
				fEventLock.wait(DEFAULT_TIMEOUT);
			}
			assertTrue(buildRemainingEventsMessage(), checkComplete());
			assertTrue("View " + VIEW_ONE + " should be open", isViewOpen(window, VIEW_ONE));
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
			window.removePerspectiveListener(this);
		}		
	}	
	
	/**
	 * Tests that context views auto-open in java perspective.
	 * Both context views should auto-open as well as standard debug views.
	 * 
	 * @throws Exception
	 */
	public void testAutoOpenJavaPerspective() throws Exception {
		String typeName = "Breakpoints";
		// first line in main
		createLineBreakpoint(52, typeName);
		
		IJavaThread thread= null;
		IWorkbenchWindow window = null;
		try {
			window = resetJavaPerspective();
			synchronized (fEventLock) {
				expectingViewOpenEvents(window, new String[]{
						VIEW_ONE,
						VIEW_TWO,
						IDebugUIConstants.ID_DEBUG_VIEW,
						IDebugUIConstants.ID_VARIABLE_VIEW,
						IDebugUIConstants.ID_BREAKPOINT_VIEW});
				thread= launchToBreakpoint(typeName);
				fEventLock.wait(DEFAULT_TIMEOUT);
			}
			assertNotNull("Breakpoint not hit within timeout period", thread);
			assertTrue(buildRemainingEventsMessage(), checkComplete());
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
			window.removePerspectiveListener(this);
		}		
	}
	
	/**
	 * Tests that context views auto-open and close in java perspective.
	 * All views should auto-close in non-standard debug perspective.
	 * 
	 * @throws Exception
	 */
	public void testAutoCloseJavaPerspective() throws Exception {
		String typeName = "Breakpoints";
		// first line in main
		createLineBreakpoint(52, typeName);
		
		IJavaThread thread= null;
		IWorkbenchWindow window = null;
		try {
			window = resetJavaPerspective();
			synchronized (fEventLock) {
				expectingViewOpenEvents(window, new String[]{
						VIEW_ONE,
						VIEW_TWO,
						IDebugUIConstants.ID_DEBUG_VIEW,
						IDebugUIConstants.ID_VARIABLE_VIEW,
						IDebugUIConstants.ID_BREAKPOINT_VIEW});
				thread= launchToBreakpoint(typeName);
				fEventLock.wait(DEFAULT_TIMEOUT);
			}
			assertNotNull("Breakpoint not hit within timeout period", thread);
			assertTrue(buildRemainingEventsMessage(), checkComplete());
			// terminate to auto close
			synchronized (fEventLock) {
				expectingViewCloseEvents(window, new String[]{
						VIEW_ONE,
						VIEW_TWO,
						IDebugUIConstants.ID_DEBUG_VIEW,
						IDebugUIConstants.ID_VARIABLE_VIEW,
						IDebugUIConstants.ID_BREAKPOINT_VIEW});
				thread.terminate();
				fEventLock.wait(DEFAULT_TIMEOUT);
			}
			assertTrue(buildRemainingEventsMessage(), checkComplete());
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
			window.removePerspectiveListener(this);
		}		
	}	
	
	protected String buildRemainingEventsMessage() {
		StringBuffer buffer = new StringBuffer();
		partsMessage("Parts did not open: ", fExpectingOpenEvents, buffer);
		partsMessage("Parts did not close: ", fExpectingCloseEvents, buffer);
		return buffer.toString();
	}
	
	private void partsMessage(String header, List partIds, StringBuffer buffer) {
		String[] ids = (String[]) partIds.toArray(new String[partIds.size()]);
		if (ids.length > 0) {
			buffer.append(header);
			for (int i = 0; i < ids.length; i++) {
				buffer.append(ids[i]);
				if (i < (ids.length - 1)) {
					buffer.append(", ");
				}
			}
		}		
	}
	
	/**
	 * Adds ids of views to 'expecting open' queue.
	 * 
	 * @param window
	 * @param viewIds
	 */
	protected void expectingViewOpenEvents(IWorkbenchWindow window, String[] viewIds) {
		for (int i = 0; i < viewIds.length; i++) {
			fExpectingOpenEvents.add(viewIds[i]);
		}
		window.addPerspectiveListener(this);
	}
	
	/**
	 * Adds ids of views to 'expecting open' queue.
	 * 
	 * @param window
	 * @param viewIds
	 */
	protected void expectingViewCloseEvents(IWorkbenchWindow window, String[] viewIds) {
		for (int i = 0; i < viewIds.length; i++) {
			fExpectingCloseEvents.add(viewIds[i]);
		}
		window.addPerspectiveListener(this);
	}	

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener3#perspectiveOpened(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveOpened(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener3#perspectiveClosed(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveClosed(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener3#perspectiveDeactivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveDeactivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener3#perspectiveSavedAs(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveSavedAs(IWorkbenchPage page, IPerspectiveDescriptor oldPerspective, IPerspectiveDescriptor newPerspective) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener2#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IWorkbenchPartReference, java.lang.String)
	 */
	public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) {
		if (changeId == IWorkbenchPage.CHANGE_VIEW_SHOW) {
			fExpectingOpenEvents.remove(partRef.getId());
		}
		if (changeId == IWorkbenchPage.CHANGE_VIEW_HIDE) {
			fExpectingCloseEvents.remove(partRef.getId());
		}
		checkComplete();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, java.lang.String)
	 */
	public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {
	}
	
	/**
	 * Check if all expected events have occurred.
	 */
	protected boolean checkComplete() {
		if (!fExpectingOpenEvents.isEmpty()) {
			return false;
		}
		// all expected events have occurred, notify
		synchronized (fEventLock) {
			fEventLock.notifyAll();
		}
		return true;
	}
}
