// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString, useForLoop, com.instantiations.assist.eclipse.analysis.deserializeabilitySecurity, com.instantiations.assist.eclipse.analysis.disallowReturnMutable, com.instantiations.assist.eclipse.analysis.enforceCloneableUsageSecurity
/*******************************************************************************
 * Copyright (c) 2010, 2013 Ericsson AB 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
 * 
 * Description:
 * 
 * This class is used to access various eclipse editors from R4E model elements
 * 
 * Contributors:
 *   Sebastien Dubois - Created for Mylyn Review R4E project
 *   
 ******************************************************************************/

package org.eclipse.mylyn.reviews.r4e.ui.internal.editors;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import org.eclipse.compare.CompareEditorInput;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion;
import org.eclipse.mylyn.reviews.r4e.ui.R4EUIPlugin;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIPosition;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIAnomalyBasic;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIComment;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIContent;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIFileContext;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIReviewItem;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUITextPosition;
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.CommandUtils;
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.UIUtils;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * @author Sebastien Dubois
 * @version $Revision: 1.0 $
 */
public class EditorProxy {

	// ------------------------------------------------------------------------
	// Constants
	// ------------------------------------------------------------------------

	/**
	 * Field DEFAULT_EDITOR_NAME. (value is ""org.eclipse.ui.DefaultTextEditor"")
	 */
	private static final String DEFAULT_EDITOR_NAME = "org.eclipse.ui.DefaultTextEditor";

	// ------------------------------------------------------------------------
	// Methods
	// ------------------------------------------------------------------------

	/**
	 * Method openEditor. Open the editor
	 * 
	 * @param aPage
	 *            IWorkbenchPage - the current workbench page
	 * @param aSelection
	 *            ISelection - the currently selected model element
	 * @param aForceSingleEditor
	 *            boolean - flag to force single editor
	 * @throws CoreException
	 */
	public static IEditorPart openEditor(IWorkbenchPage aPage, ISelection aSelection, boolean aForceSingleEditor) {

		IEditorPart editor = null;

		if (aSelection.isEmpty() || !(aSelection instanceof IStructuredSelection)) {
			return editor;
		}

		Object element = null;
		IR4EUIPosition position = null;

		R4EUIFileContext context = null;

		for (final Iterator<?> iterator = ((IStructuredSelection) aSelection).iterator(); iterator.hasNext();) {

			element = iterator.next();
			if (!(element instanceof IR4EUIModelElement)) {
				continue;
			}

			//Depending on which element was selected in the tree, we make the target file editable
			//The file is editable if it was opened from the anomaly or comment level, otherwise it is not
			//Check to get the position we should put the cursor on and the highlight range in the editor
			if (element instanceof R4EUIAnomalyBasic) {
				position = ((R4EUIAnomalyBasic) element).getPosition();
			} else if (element instanceof R4EUIComment) {
				position = ((R4EUIAnomalyBasic) ((R4EUIComment) element).getParent()).getPosition();
			} else if (element instanceof R4EUIContent) {
				position = ((R4EUIContent) element).getPosition();
			}

			//Find the parent FileContextElement
			while (!(element instanceof R4EUIFileContext)) {
				element = ((IR4EUIModelElement) element).getParent();
				if (null == element) {
					return editor;
				}
			}
			context = ((R4EUIFileContext) element);

			//If the files are the same (or do not exist), open the single editor
			if (null == context.getBaseFileVersion()
					|| null == context.getTargetFileVersion()
					|| context.getBaseFileVersion()
							.getVersionID()
							.equals(context.getTargetFileVersion().getVersionID())) {
				aForceSingleEditor = true;
			}

			//Check if the base file is set, if so, we will use the compare editor.  Otherwise we use the normal editor of the appropriate type
			if (context.isFileVersionsComparable() && !aForceSingleEditor) {
				editor = openCompareEditor(aPage, context);
			} else {
				editor = openSingleEditor(aPage, context, position);
			}
		}
		return editor;
	}

	/**
	 * Method openReviewItemCompareEditor. Open the compare editor to compare Review Items
	 * 
	 * @param aPage
	 *            IWorkbenchPage - the current workbench page
	 * @param aTargetItem
	 *            R4EUIReviewItem - the currently selected target (newer) Review Item
	 * @param aBaseItem
	 *            R4EUIReviewItem - the currently selected base (older) Review Item
	 * @throws CoreException
	 */
	public static IEditorPart openReviewItemCompareEditor(IWorkbenchPage aPage, R4EUIReviewItem aTargetItem,
			R4EUIReviewItem aBaseItem) {

		//Reuse editor if it is already open on the same input
		CompareEditorInput input = null;
		IEditorPart editor = findReusableReviewItemCompareEditor(aPage, aTargetItem, aBaseItem);

		if (null != editor) {
			//First try to activate current editor.  If it is not possible to display the element in the editor, reuse it if possible, or worse case close and re-open it
			aPage.activate(editor);
			if (!UIUtils.selectElementInEditor((R4EReviewItemCompareEditorInput) editor.getEditorInput())) {
				//Reuse editor whenever possible, otherwise close and re-open it
				if (editor instanceof IReusableEditor) {
					aPage.reuseEditor((IReusableEditor) editor, new R4EReviewItemCompareEditorInput(aTargetItem,
							aBaseItem));
					//NOTE:  The position is set in editor in R4ECompareEditorInput#createContents TODO
					return editor;
				} else {
					aPage.closeEditor(editor, true); //Close current editor
				}
			} else {
				return editor;
			}
		}

		input = new R4EReviewItemCompareEditorInput(aTargetItem, aBaseItem);

		R4EUIPlugin.Ftracer.traceInfo("Open compare editor on Review Items "
				+ ((null != aTargetItem) ? aTargetItem.getItem().getId() : "") + " (Target) and "
				+ ((null != aBaseItem) ? aBaseItem.getItem().getId() : "") + " (Base)");
		try {
			editor = aPage.openEditor(input, "org.eclipse.compare.CompareEditor", OpenStrategy.activateOnOpen());
		} catch (PartInitException e) {
			R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
			R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
		}
		//NOTE:  The position is set in editor in R4ECompareEditorInput#createContents TODO
		return editor;
	}

	/**
	 * Method openSingleEditor. Open the single-mode default editor for the file type
	 * 
	 * @param aPage
	 *            IWorkbenchPage - the current workbench page
	 * @param aContext
	 *            R4EUIFileContext - the file context
	 * @param aPosition
	 *            IR4EUIPosition - the position to go to in the file
	 * @return IEditorPart
	 */
	private static IEditorPart openSingleEditor(IWorkbenchPage aPage, R4EUIFileContext aContext,
			IR4EUIPosition aPosition) {

		R4EFileVersion version;
		IEditorPart editor = null;
		if (null != aContext.getTargetFileVersion()) {
			version = aContext.getTargetFileVersion();
		} else if (null != aContext.getBaseFileVersion()) {
			//File was removed, open the base then
			version = aContext.getBaseFileVersion();
		} else {
			//Show the error, the file was in another project and was not
			//found when creating the commit review item
			String error = "Base and target file version not found for this review item";
			R4EUIPlugin.Ftracer.traceError("Exception: " + error);
			CoreException exception = new CoreException(new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, error));
			//Display the error, but do not log in the error log
			UIUtils.displayCoreErrorDialog(exception, false);
			return editor;
		}

		try {
			IStorageEditorInput editorInput = null;

			//NOTE:  We use the workspace file as input if it is in sync with the file to review,
			//		 otherwise we use the file to review that is included in the review repository
			if (CommandUtils.useWorkspaceResource(version)) {
				editorInput = new R4EFileEditorInput(version);
			} else {
				editorInput = new R4EFileRevisionEditorInput(version);
			}
			final String id = getEditorId(editorInput.getName(),
					getContentType(editorInput.getName(), editorInput.getStorage().getContents()));
			editor = aPage.openEditor(editorInput, id, OpenStrategy.activateOnOpen());
			final ITextOperationTarget target = (ITextOperationTarget) editor.getAdapter(ITextOperationTarget.class);
			if (target instanceof SourceViewer) {
				final SourceViewer sourceViewer = (SourceViewer) target;
				UIUtils.getSingleAnnotationSupport(sourceViewer, aContext);
			}

			//Set highlighted selection and reset cursor if possible
			if (editor instanceof ITextEditor && aPosition instanceof R4EUITextPosition) {
				final int offset = ((R4EUITextPosition) aPosition).getOffset();
				final int length = ((R4EUITextPosition) aPosition).getLength();
				((ITextEditor) editor).setHighlightRange(offset, length, true);
				final TextSelection selectedText = new TextSelection(offset, length);
				((ITextEditor) editor).getSelectionProvider().setSelection(selectedText);
			}
		} catch (CoreException e) {
			UIUtils.displayCoreErrorDialog(e);
		}
		return editor;
	}

	/**
	 * Method openCompareEditor. Open the compare-mode default editor for the file types
	 * 
	 * @param aPage
	 *            IWorkbenchPage - the current workbench page
	 * @param aContext
	 *            R4EUIFileContext - the file Context (base and target) to open
	 * @return IEditorPart
	 */
	private static IEditorPart openCompareEditor(IWorkbenchPage aPage, R4EUIFileContext aContext) {
		//Reuse editor if it is already open on the same input
		CompareEditorInput input = null;
		IEditorPart editor = findReusableFileContextCompareEditor(aPage, aContext.getTargetFileVersion(),
				aContext.getBaseFileVersion());

		if (null != editor) {
			//First try to activate current editor.  If it is not possible to display the element in the editor, reuse it if possible, or worse case close and re-open it
			aPage.activate(editor);
			if (!UIUtils.selectElementInEditor((R4EFileContextCompareEditorInput) editor.getEditorInput())) {
				//Reuse editor whenever possible, otherwise close and re-open it
				if (editor instanceof IReusableEditor) {
					aPage.reuseEditor((IReusableEditor) editor, new R4EFileContextCompareEditorInput(aContext));
					//NOTE:  The position is set in editor in R4ECompareEditorInput#createContents
					return editor;
				} else {
					aPage.closeEditor(editor, true); //Close current editor
				}
			} else {
				return editor;
			}
		}
		input = new R4EFileContextCompareEditorInput(aContext);

		R4EUIPlugin.Ftracer.traceInfo("Open compare editor on files "
				+ ((null != aContext.getTargetFileVersion()) ? aContext.getTargetFileVersion().getName() : "")
				+ " (Target) and "
				+ ((null != aContext.getBaseFileVersion()) ? aContext.getBaseFileVersion().getName() : "") + " (Base)");
		try {
			editor = aPage.openEditor(input, "org.eclipse.compare.CompareEditor", OpenStrategy.activateOnOpen());
		} catch (PartInitException e) {
			R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
			R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
		}
		//NOTE:  The position is set in editor in R4ECompareEditorInput#createContents
		return editor;
	}

	/**
	 * Method findReusableCompareEditor. Find the appropriate file context compare editor based on the file types
	 * 
	 * @param aPage
	 *            IWorkbenchPage - the current workbench page
	 * @param aTargetFile
	 *            R4EFileVersion - the target file version
	 * @param aBaseFile
	 *            R4EFileVersion - the base (or reference) file version
	 * @return IEditorPart - the editor to use
	 */
	public static IEditorPart findReusableFileContextCompareEditor(IWorkbenchPage aPage, R4EFileVersion aTargetFile,
			R4EFileVersion aBaseFile) {

		final IEditorReference[] editorRefs = aPage.getEditorReferences();
		IEditorPart part = null;
		R4EFileContextCompareEditorInput input = null;
		// first loop looking for an editor with the same input
		for (IEditorReference editorRef : editorRefs) {
			part = editorRef.getEditor(false);
			if (null != part && part instanceof IReusableEditor) {
				// check if the editor input type complies with the types given by the caller
				if (R4EFileContextCompareEditorInput.class.isInstance(part.getEditorInput())) {
					//Now check if the input files are the same as with the found editor
					input = (R4EFileContextCompareEditorInput) part.getEditorInput();
					R4EFileVersion leftVersion = input.getCurrentDiffNode().getTargetVersion();
					R4EFileVersion rightVersion = input.getCurrentDiffNode().getBaseVersion();

					//Case:  No input in editor, that should never happen but guard here just in case
					if (null == leftVersion && null == rightVersion) {
						return null;
					}

					//Case:  No target file and base is the same
					if (null == leftVersion && null == aTargetFile && null != rightVersion && null != aBaseFile
							&& rightVersion.equals(aBaseFile)) {
						return part;
					}

					//Case:  No base file and target is the same
					if (null == rightVersion && null == aBaseFile && null != leftVersion && null != aTargetFile
							&& leftVersion.equals(aTargetFile)) {
						return part;
					}

					//Case: Base and target are the same
					if (null != leftVersion && null != rightVersion && null != aBaseFile && null != aTargetFile) {
						if (CommandUtils.isSameFileVersion(leftVersion, aTargetFile)
								&& CommandUtils.isSameFileVersion(rightVersion, aBaseFile)) {
							return part;
						}
					}
				}
			}
		}
		// no re-usable editor found
		return null;
	}

	/**
	 * Method findReusableCompareEditor. Find the appropriate Review Item compare editor based on the file types
	 * 
	 * @param aPage
	 *            IWorkbenchPage - the current workbench page
	 * @param aTargetItem
	 *            R4EUIReviewItem - the target review item
	 * @param aBaseItem
	 *            R4EUIReviewItem - the base (or reference) review item
	 * @return IEditorPart - the editor to use
	 */
	public static IEditorPart findReusableReviewItemCompareEditor(IWorkbenchPage aPage, R4EUIReviewItem aTargetItem,
			R4EUIReviewItem aBaseItem) {

		final IEditorReference[] editorRefs = aPage.getEditorReferences();
		IEditorPart part = null;
		R4EReviewItemCompareEditorInput input = null;
		// first loop looking for an editor with the same input
		for (IEditorReference editorRef : editorRefs) {
			part = editorRef.getEditor(false);
			if (null != part && part instanceof IReusableEditor) {
				// check if the editor input type complies with the types given by the caller
				if (R4EReviewItemCompareEditorInput.class.isInstance(part.getEditorInput())) {
					//Now check if the input files are the same as with the found editor
					input = (R4EReviewItemCompareEditorInput) part.getEditorInput();
					if ((aBaseItem == null || aBaseItem.equals(input.getBaseReviewItem()))
							&& aTargetItem.equals(input.getTargetReviewItem())) {
						return part;
					}
				}
			}
		}
		// no re-usable editor found
		return null;
	}

	/**
	 * Method getReviewItemCompareEditorPart. Find the appropriate editor for this review item
	 * 
	 * @param aPage
	 *            IWorkbenchPage - the current workbench page
	 * @param aItem
	 *            R4EUIReviewItem - the target review item
	 * @return IEditorPart - the editor to use
	 */
	public static IEditorPart getReviewItemCompareEditorPart(IWorkbenchPage aPage, R4EUIReviewItem aItem) {
		final IEditorReference[] editorRefs = aPage.getEditorReferences();
		IEditorPart part = null;
		R4EReviewItemCompareEditorInput input = null;
		// first loop looking for an editor with the same input
		for (IEditorReference editorRef : editorRefs) {
			part = editorRef.getEditor(false);
			if (null != part && part instanceof IReusableEditor) {
				// check if the editor input type complies with the types given by the caller
				if (R4EReviewItemCompareEditorInput.class.isInstance(part.getEditorInput())) {
					//Now check if the input review item is the same as with the found editor
					input = (R4EReviewItemCompareEditorInput) part.getEditorInput();
					if (aItem.equals(input.getTargetReviewItem()) || aItem.equals(input.getBaseReviewItem())) {
						return part;
					}
				}
			}
		}
		// no re-usable editor found
		return null;
	}

	/**
	 * Method findReusableEditor. Find the appropriate editor based on the file types
	 * 
	 * @param aPage
	 *            IWorkbenchPage - the current workbench page
	 * @param aFile
	 *            R4EFileVersion - the target file version
	 * @return IEditorPart - the editor to use
	 */
	public static IEditorPart findReusableEditor(IWorkbenchPage aPage, R4EFileVersion aFileVersion) {

		final IEditorReference[] editorRefs = aPage.getEditorReferences();
		IEditorPart part = null;
		// first loop looking for an editor with the same input
		for (IEditorReference editorRef : editorRefs) {
			part = editorRef.getEditor(false);
			if (null != part) {
				// check if the editor input type complies with the types given by the caller
				if (R4EFileEditorInput.class.isInstance(part.getEditorInput())) {
					//Now check if the input files are the same as with the found editor
					R4EFileEditorInput input = (R4EFileEditorInput) part.getEditorInput();

					//Case:  No input in editor, that should never happen but guard here just in case
					if (null != input) {

						//Get the file version
						R4EFileVersion fileVersion = input.getFileVersion();
						if (null != fileVersion && null != aFileVersion
								&& CommandUtils.isSameFileVersion(fileVersion, aFileVersion)) {
							return part;
						}
					}
				} else if (R4EFileRevisionEditorInput.class.isInstance(part.getEditorInput())) {
					//Now check if the input files are the same as with the found editor
					R4EFileRevisionEditorInput input = (R4EFileRevisionEditorInput) part.getEditorInput();

					//Case:  No input in editor, that should never happen but guard here just in case
					if (null != input) {

						//Get the file version
						R4EFileVersion fileVersion = input.getFileVersion();
						if (null != fileVersion && null != aFileVersion
								&& CommandUtils.isSameFileVersion(fileVersion, aFileVersion)) {
							return part;
						}
					}
				}
			}
		}
		// no re-usable editor found
		return null;
	}

	/**
	 * Method getEditorId.
	 * 
	 * @param aFileName
	 *            String
	 * @param aType
	 *            IContentType
	 * @return String
	 */
	private static String getEditorId(String aFileName, IContentType aType) {
		final IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
		final IEditorDescriptor descriptor = registry.getDefaultEditor(aFileName, aType);
		String id = null;
		if (null == descriptor || descriptor.isOpenExternal()) {
			id = DEFAULT_EDITOR_NAME;
		} else {
			id = descriptor.getId();
		}
		return id;
	}

	/**
	 * Method getContentType.
	 * 
	 * @param aFileName
	 *            String
	 * @param aContents
	 *            InputStream
	 * @return IContentType
	 */
	private static IContentType getContentType(String aFileName, InputStream aContents) {
		IContentType type = null;
		if (null != aContents) {
			try {
				type = Platform.getContentTypeManager().findContentTypeFor(aContents, aFileName);
			} catch (IOException e) {
				R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
				R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
			}
		}
		if (null == type) {
			type = Platform.getContentTypeManager().findContentTypeFor(aFileName);
		}
		return type;
	}
}
