/*******************************************************************************
 * 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.text.tests.performance;


import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

import junit.framework.Assert;

import org.eclipse.core.filebuffers.tests.FileTool;
import org.eclipse.core.filebuffers.tests.ResourceHelper;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
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.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.text.tests.Accessor;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IWidgetTokenKeeper;
import org.eclipse.jface.text.IWidgetTokenOwner;
import org.eclipse.jface.text.reconciler.AbstractReconciler;
import org.eclipse.jface.text.source.SourceViewer;

import org.eclipse.jdt.ui.PreferenceConstants;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.dialogs.OptionalMessageDialog;
import org.eclipse.jdt.internal.ui.text.JavaReconciler;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameRequestor;
import org.eclipse.jdt.testplugin.JavaProjectHelper;
import org.eclipse.jdt.text.tests.JdtTextTestPlugin;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;


/**
 * @since 3.1
 */
public class EditorTestHelper {
	
	private static class ImportOverwriteQuery implements IOverwriteQuery {
		public String queryOverwrite(String file) {
			return ALL;
		}	
	}		
	private static class Requestor extends TypeNameRequestor {
	}
	
	public static final String TEXT_EDITOR_ID= "org.eclipse.ui.DefaultTextEditor";
	
	public static final String COMPILATION_UNIT_EDITOR_ID= "org.eclipse.jdt.ui.CompilationUnitEditor";
	
	public static final String RESOURCE_PERSPECTIVE_ID= "org.eclipse.ui.resourcePerspective";
	
	public static final String JAVA_PERSPECTIVE_ID= "org.eclipse.jdt.ui.JavaPerspective";
	
	public static final String OUTLINE_VIEW_ID= "org.eclipse.ui.views.ContentOutline";
	
	public static final String PACKAGE_EXPLORER_VIEW_ID= "org.eclipse.jdt.ui.PackageExplorer";
	
	public static final String NAVIGATOR_VIEW_ID= "org.eclipse.ui.views.ResourceNavigator";
	
	public static final String INTRO_VIEW_ID= "org.eclipse.ui.internal.introview";
	
	public static IEditorPart openInEditor(IFile file, boolean runEventLoop) throws PartInitException {
		IEditorPart part= IDE.openEditor(getActivePage(), file);
		if (runEventLoop)
			runEventQueue(part);
		return part;
	}
	
	public static IEditorPart openInEditor(IFile file, String editorId, boolean runEventLoop) throws PartInitException {
		IEditorPart part= IDE.openEditor(getActivePage(), file, editorId);
		if (runEventLoop)
			runEventQueue(part);
		return part;
	}
	
	public static AbstractTextEditor[] openInEditor(IFile[] files, String editorId) throws PartInitException {
		AbstractTextEditor editors[]= new AbstractTextEditor[files.length];
		for (int i= 0; i < files.length; i++) {
			editors[i]= (AbstractTextEditor) openInEditor(files[i], editorId, true);
			joinReconciler(getSourceViewer(editors[i]), 100, 10000, 100);
		}
		return editors;
	}
	
	public static IDocument getDocument(ITextEditor editor) {
		IDocumentProvider provider= editor.getDocumentProvider();
		IEditorInput input= editor.getEditorInput();
		return provider.getDocument(input);
	}
	
	public static void revertEditor(ITextEditor editor, boolean runEventQueue) {
		editor.doRevertToSaved();
		if (runEventQueue)
			runEventQueue(editor);
	}
	
	public static void closeEditor(IEditorPart editor) {
		IWorkbenchPartSite site;
		IWorkbenchPage page;
		if (editor != null && (site= editor.getSite()) != null && (page= site.getPage()) != null)
			page.closeEditor(editor, false);
	}
	
	public static void closeAllEditors() {
		IWorkbenchWindow[] windows= PlatformUI.getWorkbench().getWorkbenchWindows();
		for (int i= 0; i < windows.length; i++) {
			IWorkbenchPage[] pages= windows[i].getPages();
			for (int j= 0; j < pages.length; j++) {
				IEditorReference[] editorReferences= pages[j].getEditorReferences();
				for (int k= 0; k < editorReferences.length; k++)
					closeEditor(editorReferences[k].getEditor(false));
			}
		}
	}
	
	/**
	 * Runs the event queue on the current display until it is empty.
	 */
	public static void runEventQueue() {
		IWorkbenchWindow window= getActiveWorkbenchWindow();
		if (window != null)
			runEventQueue(window.getShell());
	}
	
	public static void runEventQueue(IWorkbenchPart part) {
		runEventQueue(part.getSite().getShell());
	}
	
	public static void runEventQueue(Shell shell) {
		runEventQueue(shell.getDisplay());
	}
	
	public static void runEventQueue(Display display) {
		while (display.readAndDispatch()) {
			// do nothing
		}
	}
	
	/**
	 * Runs the event queue on the current display and lets it sleep until the
	 * timeout elapses.
	 * 
	 * @param millis the timeout in milliseconds
	 */
	public static void runEventQueue(long millis) {
		runEventQueue(getActiveDisplay(), millis);
	}
	
	public static void runEventQueue(IWorkbenchPart part, long millis) {
		runEventQueue(part.getSite().getShell(), millis);
	}
	
	public static void runEventQueue(Shell shell, long millis) {
		runEventQueue(shell.getDisplay(), millis);
	}
	
	public static void runEventQueue(Display display, long minTime) {
		if (display != null) {
			DisplayHelper.sleep(display, minTime);
		} else {
			sleep((int) minTime);
		}
	}
	
	public static IWorkbenchWindow getActiveWorkbenchWindow() {
		return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
	}
	
	public static void forceFocus() {
		IWorkbenchWindow window= getActiveWorkbenchWindow();
		if (window == null) {
			IWorkbenchWindow[] wbWindows= PlatformUI.getWorkbench().getWorkbenchWindows();
			if (wbWindows.length == 0)
				return;
			window= wbWindows[0];
		}
		Shell shell= window.getShell();
		if (shell != null && !shell.isDisposed()) {
			shell.forceActive();
			shell.forceFocus();
		}
	}
	
	public static IWorkbenchPage getActivePage() {
		IWorkbenchWindow window= getActiveWorkbenchWindow();
		return window != null ? window.getActivePage() : null;
	}
	
	public static Display getActiveDisplay() {
		IWorkbenchWindow window= getActiveWorkbenchWindow();
		return window != null ? window.getShell().getDisplay() : null;
	}
	
	public static void joinBackgroundActivities(AbstractTextEditor editor) throws CoreException {
		joinBackgroundActivities(getSourceViewer(editor));
	}
	
	public static void joinBackgroundActivities(SourceViewer sourceViewer) throws CoreException {
		joinBackgroundActivities();
		joinReconciler(sourceViewer, 500, 0, 500);
	}
	
	public static void joinBackgroundActivities() throws CoreException {
		// Join Building
		Logger.global.entering("EditorTestHelper", "joinBackgroundActivities");
		Logger.global.finer("join builder");
		boolean interrupted= true;
		while (interrupted) {
			try {
				Platform.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null);
				interrupted= false;
			} catch (InterruptedException e) {
				interrupted= true;
			}
		}
		// Join indexing
		Logger.global.finer("join indexer");
		new SearchEngine().searchAllTypeNames(
				null,
				"XXXXXXXXX".toCharArray(), // make sure we search a concrete name. This is faster according to Kent 
				SearchPattern.R_EXACT_MATCH,
				IJavaSearchConstants.CLASS,
				SearchEngine.createJavaSearchScope(new IJavaElement[0]),
				new Requestor(),
				IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
				null);
		// Join jobs
		joinJobs(0, 0, 500);
		Logger.global.exiting("EditorTestHelper", "joinBackgroundActivities");
	}
	
	public static boolean joinJobs(long minTime, long maxTime, long intervalTime) {
		Logger.global.entering("EditorTestHelper", "joinJobs");
		runEventQueue(minTime);
		
		DisplayHelper helper= new DisplayHelper() {
			public boolean condition() {
				return allJobsQuiet();
			}
		};
		boolean quiet= helper.waitForCondition(getActiveDisplay(), maxTime > 0 ? maxTime : Long.MAX_VALUE, intervalTime);
		Logger.global.exiting("EditorTestHelper", "joinJobs", new Boolean(quiet));
		return quiet;
	}
	
	public static void sleep(int intervalTime) {
		try {
			Thread.sleep(intervalTime);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static boolean allJobsQuiet() {
		IJobManager jobManager= Platform.getJobManager();
		Job[] jobs= jobManager.find(null);
		for (int i= 0; i < jobs.length; i++) {
			Job job= jobs[i];
			int state= job.getState();
			if (state == Job.RUNNING || state == Job.WAITING) {
				Logger.global.finest(job.toString());
				return false;
			}
		}
		return true;
	}
	
	public static boolean isViewShown(String viewId) {
		return getActivePage().findViewReference(viewId) != null;
	}
	
	public static boolean showView(String viewId, boolean show) throws PartInitException {
		IWorkbenchPage activePage= getActivePage();
		IViewReference view= activePage.findViewReference(viewId);
		boolean shown= view != null;
		if (shown != show)
			if (show)
				activePage.showView(viewId);
			else
				activePage.hideView(view);
		return shown;
	}
	
	public static void bringToTop() {
		getActiveWorkbenchWindow().getShell().forceActive();
	}
	
	public static void forceReconcile(SourceViewer sourceViewer) {
		Accessor reconcilerAccessor= new Accessor(getReconciler(sourceViewer), AbstractReconciler.class);
		reconcilerAccessor.invoke("forceReconciling", new Object[0]);
	}
	
	public static boolean joinReconciler(SourceViewer sourceViewer, long minTime, long maxTime, long intervalTime) {
		Logger.global.entering("EditorTestHelper", "joinReconciler");
		runEventQueue(minTime);
		
		AbstractReconciler reconciler= getReconciler(sourceViewer);
		if (reconciler == null)
			return true;
		final Accessor backgroundThreadAccessor= getBackgroundThreadAccessor(reconciler);
		final Accessor javaReconcilerAccessor;
		if (reconciler instanceof JavaReconciler)
			javaReconcilerAccessor= new Accessor(reconciler, JavaReconciler.class);
		else
			javaReconcilerAccessor= null;
		
		DisplayHelper helper= new DisplayHelper() {
			public boolean condition() {
				return !isRunning(javaReconcilerAccessor, backgroundThreadAccessor);
			}
		};
		boolean finished= helper.waitForCondition(getActiveDisplay(), maxTime > 0 ? maxTime : Long.MAX_VALUE, intervalTime);
		Logger.global.exiting("EditorTestHelper", "joinReconciler", new Boolean(finished));
		return finished;
	}
	
	public static AbstractReconciler getReconciler(SourceViewer sourceViewer) {
		return (AbstractReconciler) new Accessor(sourceViewer, SourceViewer.class).get("fReconciler");
	}
	
	public static SourceViewer getSourceViewer(AbstractTextEditor editor) {
		SourceViewer sourceViewer= (SourceViewer) new Accessor(editor, AbstractTextEditor.class).invoke("getSourceViewer", new Object[0]);
		return sourceViewer;
	}
	
	private static Accessor getBackgroundThreadAccessor(AbstractReconciler reconciler) {
		Object backgroundThread= new Accessor(reconciler, AbstractReconciler.class).get("fThread");
		return new Accessor(backgroundThread, backgroundThread.getClass());
	}
	
	private static boolean isRunning(Accessor javaReconcilerAccessor, Accessor backgroundThreadAccessor) {
		return (javaReconcilerAccessor != null ? !isInitialProcessDone(javaReconcilerAccessor) : false) || isDirty(backgroundThreadAccessor) || isActive(backgroundThreadAccessor);
	}
	
	private static boolean isInitialProcessDone(Accessor javaReconcilerAccessor) {
		return ((Boolean) javaReconcilerAccessor.get("fIninitalProcessDone")).booleanValue();
	}
	
	private static boolean isDirty(Accessor backgroundThreadAccessor) {
		return ((Boolean) backgroundThreadAccessor.invoke("isDirty", new Object[0])).booleanValue();
	}
	
	private static boolean isActive(Accessor backgroundThreadAccessor) {
		return ((Boolean) backgroundThreadAccessor.invoke("isActive", new Object[0])).booleanValue();
	}
	
	public static String showPerspective(String perspective) throws WorkbenchException {
		String shownPerspective= getActivePage().getPerspective().getId();
		if (!perspective.equals(shownPerspective)) {
			IWorkbench workbench= PlatformUI.getWorkbench();
			IWorkbenchWindow activeWindow= workbench.getActiveWorkbenchWindow();
			workbench.showPerspective(perspective, activeWindow);
		}
		return shownPerspective;
	}
	
	public static void closeAllPopUps(SourceViewer sourceViewer) {
		IWidgetTokenKeeper tokenKeeper= new IWidgetTokenKeeper() {
			public boolean requestWidgetToken(IWidgetTokenOwner owner) {
				return true;
			}
		};
		sourceViewer.requestWidgetToken(tokenKeeper, Integer.MAX_VALUE);
		sourceViewer.releaseWidgetToken(tokenKeeper);
	}
	
	public static void resetFolding() {
		JavaPlugin.getDefault().getPreferenceStore().setToDefault(PreferenceConstants.EDITOR_FOLDING_ENABLED);
	}
	
	public static boolean enableFolding(boolean value) {
		IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore();
		boolean oldValue= preferenceStore.getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
		if (value != oldValue)
			preferenceStore.setValue(PreferenceConstants.EDITOR_FOLDING_ENABLED, value);
		return oldValue;
	}
	
	public static IJavaProject createJavaProject(String project, String externalSourceFolder) throws CoreException, JavaModelException {
		return createJavaProject(project, externalSourceFolder, false);
	}
	
	public static IJavaProject createJavaProject(String project, String externalSourceFolder, boolean linkSourceFolder) throws CoreException, JavaModelException {
		IJavaProject javaProject= JavaProjectHelper.createJavaProject(project, "bin");
		Assert.assertNotNull("JRE is null", JavaProjectHelper.addRTJar(javaProject));
		IFolder folder;
		if (linkSourceFolder)
			folder= ResourceHelper.createLinkedFolder((IProject) javaProject.getUnderlyingResource(), new Path("src"), JdtTextTestPlugin.getDefault(), new Path(externalSourceFolder));
		else {
			folder= ((IProject) javaProject.getUnderlyingResource()).getFolder("src");
			importFilesFromDirectory(FileTool.getFileInPlugin(JdtTextTestPlugin.getDefault(), new Path(externalSourceFolder)), folder.getFullPath(), null);
		}
		Assert.assertNotNull(folder);
		Assert.assertTrue(folder.exists());
		JavaProjectHelper.addSourceContainer(javaProject, "src");
		return javaProject;
	}
	
	public static IFile[] findFiles(IResource resource) throws CoreException {
		List files= new ArrayList();
		findFiles(resource, files);
		return (IFile[]) files.toArray(new IFile[files.size()]);
	}
	
	private static void findFiles(IResource resource, List files) throws CoreException {
		if (resource instanceof IFile) {
			files.add(resource);
			return;
		}
		if (resource instanceof IContainer) {
			IResource[] resources= ((IContainer) resource).members();
			for (int i= 0; i < resources.length; i++)
				findFiles(resources[i], files);
		}
	}
	
	public static boolean setDialogEnabled(String id, boolean enabled) {
		boolean wasEnabled= OptionalMessageDialog.isDialogEnabled(id);
		if (wasEnabled != enabled)
			OptionalMessageDialog.setDialogEnabled(id, enabled);
		return wasEnabled;
	}
	
	public static void importFilesFromDirectory(File rootDir, IPath destPath, IProgressMonitor monitor) throws CoreException {		
		try {
			IImportStructureProvider structureProvider= FileSystemStructureProvider.INSTANCE;
			List files= new ArrayList(100);
			addJavaFiles(rootDir, files);
			ImportOperation op= new ImportOperation(destPath, rootDir, structureProvider, new ImportOverwriteQuery(), files);
			op.setCreateContainerStructure(false);
			op.run(monitor);
		} catch (Exception x) {
			throw newCoreException(x);
		}
	}	
	
	private static CoreException newCoreException(Throwable x) {
		return new CoreException(new Status(IStatus.ERROR, JdtTextTestPlugin.PLUGIN_ID, -1, "", x));
	}

	private static void addJavaFiles(File dir, List collection) throws IOException {
		File[] files= dir.listFiles();
		List subDirs= new ArrayList(2);
		for (int i= 0; i < files.length; i++) {
			if (files[i].isFile()) {
				collection.add(files[i]);
			} else if (files[i].isDirectory()) {
				subDirs.add(files[i]);
			}
		}
		Iterator iter= subDirs.iterator();
		while (iter.hasNext()) {
			File subDir= (File)iter.next();
			addJavaFiles(subDir, collection);
		}
	}
}
