/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.compare.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.IPropertyChangeNotifier;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IFindReplaceTarget;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.Saveable;
import org.eclipse.ui.SaveablesLifecycleEvent;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.ui.texteditor.ITextEditorExtension3;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

/**
 * A CompareEditor takes a ICompareEditorInput as input.
 * Most functionality is delegated to the ICompareEditorInput.
 */
public class CompareEditor extends EditorPart
		implements IReusableEditor, ISaveablesSource, IPropertyChangeListener,
		ISaveablesLifecycleListener {
	public final static String CONFIRM_SAVE_PROPERTY= "org.eclipse.compare.internal.CONFIRM_SAVE_PROPERTY"; //$NON-NLS-1$

	private static final int UNINITIALIZED = 0;
	private static final int INITIALIZING = 1;
	private static final int NO_DIFF = 2;
	private static final int CANCELED = 3;
	private static final int INITIALIZED = 4;
	private static final int ERROR = 5;
	private static final int STILL_INITIALIZING = 6;
	private static final int CREATING_CONTROL = 7;
	private static final int DONE = 8;

	private IActionBars fActionBars;

	private PageBook fPageBook;

	/** the SWT control from the compare editor input*/
	private Control fControl;
	/** the outline page */
	private CompareOutlinePage fOutlinePage;

	private CompareSaveable fSaveable;

	private Control initializingPage;
	private Control emptyPage;

	private int state = UNINITIALIZED;
	private HashSet<Saveable> knownSaveables;

	private final EditorCompareContainer fContainer = new EditorCompareContainer();

	private class EditorCompareContainer extends CompareContainer {
		@Override
		public void registerContextMenu(MenuManager menu, ISelectionProvider provider) {
			if (getSite() instanceof IEditorSite) {
				IEditorSite es = (IEditorSite) getSite();
				es.registerContextMenu(menu, provider, true);
			}
		}

		@Override
		public void setStatusMessage(String message) {
			if (fActionBars != null) {
				IStatusLineManager slm= fActionBars.getStatusLineManager();
				if (slm != null) {
					slm.setMessage(message);
				}
			}
		}

		@Override
		public IServiceLocator getServiceLocator() {
			return getSite();
		}

		@Override
		protected WorkerJob createWorkerJob() {
			WorkerJob workerJob = new WorkerJob(getWorkerJobName()) {
				@Override
				public boolean belongsTo(Object family) {
					if (family == CompareEditor.this)
						return true;
					return super.belongsTo(family);
				}
			};
			return workerJob;
		}

		@Override
		protected String getWorkerJobName() {
			return NLS.bind(CompareMessages.CompareEditor_2, getTitle());
		}

		@Override
		public IWorkbenchPart getWorkbenchPart() {
			return CompareEditor.this;
		}

		@Override
		public IActionBars getActionBars() {
			return CompareEditor.this.getActionBars();
		}
	}

	/**
	 * No-argument constructor required for extension points.
	 */
	public CompareEditor() {
		// empty default implementation
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(Class<T> key) {
		if (key.equals(IContentOutlinePage.class)) {
			Object object= getCompareConfiguration().getProperty(CompareConfiguration.USE_OUTLINE_VIEW);
			if (object instanceof Boolean && ((Boolean)object).booleanValue()) {
				if (fOutlinePage != null) {
					if (fOutlinePage.getControl() != null && fOutlinePage.getControl().isDisposed()) {
						fOutlinePage = null;
					} else {
						return (T) fOutlinePage;
					}
				}
				fOutlinePage= new CompareOutlinePage(this);
				return (T) fOutlinePage;
			}
		}

		if (key == IShowInSource.class
				|| key == OutlineViewerCreator.class
				|| key == IFindReplaceTarget.class) {
			Object input = getEditorInput();
			if (input != null) {
				return Adapters.adapt(input, key);
			}
		}

		if (key == IEditorInput.class) {
			// return (T) Adapters.adapt(getEditorInput(), IEditorInput.class);
			// The above call cannot be used because the return type of getEditorInput()
			// call is IEditorInput and this itself will be returned by the above function.
			// What we want is to call getAdapter call on this IEditorInput object.
			return (T) getEditorInput().getAdapter(IEditorInput.class);
		}

		if (key == ITextEditorExtension3.class) {
			return (T) Adapters.adapt(getEditorInput(), ITextEditorExtension3.class);
		}

		return super.getAdapter(key);
	}

	/*
	 * Helper method used by ComapreEditorConfiguration to get at the compare configuration of the editor
	 */
	CompareConfiguration getCompareConfiguration() {
		IEditorInput input= getEditorInput();
		if (input instanceof CompareEditorInput)
			return ((CompareEditorInput)input).getCompareConfiguration();
		return null;
	}

	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		if (!(input instanceof CompareEditorInput))
			throw new PartInitException(Utilities.getString("CompareEditor.invalidInput")); //$NON-NLS-1$

		setSite(site);
		setInput(input);
	}

	@Override
	public void setInput(IEditorInput input) {
		if (!(input instanceof CompareEditorInput)) {
			IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, Utilities.getString("CompareEditor.invalidInput"), null); //$NON-NLS-1$
			String title= Utilities.getString("CompareEditor.error.setinput.title"); //$NON-NLS-1$
			String msg= Utilities.getString("CompareEditor.error.setinput.message"); //$NON-NLS-1$
			ErrorDialog.openError(getSite().getShell(), title, msg, s);
			return;
		}
		doSetInput(input);
		// Need to refresh the contributor (see #67888)
		refreshActionBarsContributor();
	}

	public void refreshActionBarsContributor() {
		IEditorSite editorSite= getEditorSite();
		if (editorSite != null) {
			IEditorActionBarContributor actionBarContributor= editorSite.getActionBarContributor();
			if (actionBarContributor != null) {
					actionBarContributor.setActiveEditor(null);
					actionBarContributor.setActiveEditor(this);
			}
		}
	}

	private void doSetInput(IEditorInput input) {
		IEditorInput oldInput= getEditorInput();
		disconnectFromInput(oldInput);
		Point oldSize = null;
		boolean hadPreviousInput = oldInput != null;
		if (hadPreviousInput) {
			// Cancel any jobs associated with the old input
			Job.getJobManager().cancel(this);
			if (fControl != null && !fControl.isDisposed()) {
				oldSize= fControl.getSize();
				if (emptyPage == null)
					emptyPage = new Composite(fPageBook, SWT.NONE);
				fPageBook.showPage(emptyPage);
				fControl.dispose();
				fControl = null;
			}
		}

		super.setInput(input);

		if (fOutlinePage != null)
			fOutlinePage.reset();

		final CompareEditorInput cei= (CompareEditorInput) input;
		cei.setContainer(fContainer);
		setTitleImage(cei.getTitleImage());
		setPartName(cei.getTitle());
		setTitleToolTip(cei.getToolTipText());

		if (input instanceof IPropertyChangeNotifier)
			((IPropertyChangeNotifier)input).addPropertyChangeListener(this);

		setState(cei.getCompareResult() == null ? INITIALIZING : INITIALIZED);
		if (fPageBook != null)
			createCompareControl();
		if (fControl != null && oldSize != null)
			fControl.setSize(oldSize);

		boolean hasResult = cei.getCompareResult() != null;
		if (!hasResult) {
			initializeInBackground(cei, hadPreviousInput);
		}

		firePropertyChange(IWorkbenchPartConstants.PROP_INPUT);

		// We only need to notify of new Saveables if we are changing inputs
		if (hadPreviousInput && hasResult) {
			registerSaveable();
		}
	}

	private void registerSaveable() {
		ISaveablesLifecycleListener lifecycleListener= getSite().getService(ISaveablesLifecycleListener.class);
		lifecycleListener.handleLifecycleEvent(
			new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_OPEN, internalGetSaveables(true), false));
	}

	private void disconnectFromInput(IEditorInput oldInput) {
		if (oldInput != null) {
			if (oldInput instanceof IPropertyChangeNotifier)
				((IPropertyChangeNotifier)oldInput).removePropertyChangeListener(this);

			// Let the workbench know that the old input's saveables are no longer needed
			if (knownSaveables != null && !knownSaveables.isEmpty()) {
				ISaveablesLifecycleListener lifecycleListener= getSite().getService(ISaveablesLifecycleListener.class);
				lifecycleListener.handleLifecycleEvent(
						new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_CLOSE, knownSaveables.toArray(new Saveable[knownSaveables.size()]), false));
				knownSaveables.clear();
			}
		}
	}

	protected void initializeInBackground(final CompareEditorInput cei, final boolean hadPreviousInput) {
		// Need to cancel any running jobs associated with the oldInput
		Job job = new Job(NLS.bind(CompareMessages.CompareEditor_0, cei.getTitle())) {
			@Override
			protected IStatus run(final IProgressMonitor monitor) {
				final int[] newState = new int[] { ERROR };
				try {
					IStatus status = CompareUIPlugin.getDefault().prepareInput(cei, monitor);
					if (status.isOK()) {
						// We need to update the saveables list
						newState[0] = INITIALIZED;
						return Status.OK_STATUS;
					}
					if (status.getCode() == CompareUIPlugin.NO_DIFFERENCE) {
						newState[0] = NO_DIFF;
						return Status.OK_STATUS;
					}
					newState[0] = ERROR;
					return status;
				} catch (OperationCanceledException e) {
					newState[0] = CANCELED;
					return Status.CANCEL_STATUS;
				} finally {
					if (monitor.isCanceled())
						newState[0] = CANCELED;
					Display.getDefault().syncExec(() -> {
						if (fPageBook.isDisposed())
							return;
						// we need to register the saveable if we had a previous input or if
						// there are knownSaveables (which means that the workbench called
						// getSaveables and got an empty list
						if (hadPreviousInput || (knownSaveables != null && !isAllSaveablesKnown())) {
							registerSaveable();
						}
						setState(newState[0]);
						createCompareControl();
					});
					monitor.done();
				}
			}
			@Override
			public boolean belongsTo(Object family) {
				if (family == CompareEditor.this || family == cei)
					return true;
				return cei.belongsTo(family);
			}
		};
		job.setUser(true);
		Utilities.schedule(job, getSite());
	}

	/*
	 * Helper method used to find an action bars using the Utilities#findActionsBars(Control)
	 */
	public IActionBars getActionBars() {
		return fActionBars;
	}

	/**
	 * Sets the action bars so the Utilities class can access it.
	 */
	void setActionBars(IActionBars actionBars) {
		fActionBars= actionBars;
	}

	@Override
	public void createPartControl(Composite parent) {
		parent.setData(this);
		fPageBook = new PageBook(parent, SWT.NONE);
		createCompareControl();
		IContextService service = getSite().getService(IContextService.class);
		if (service != null) {
			service.activateContext("org.eclipse.compare.compareEditorScope"); //$NON-NLS-1$
			service.activateContext("org.eclipse.ui.textEditorScope"); //$NON-NLS-1$
		}
	}

	private void createCompareControl() {
		if (fPageBook.isDisposed())
			return;
		IEditorInput input= getEditorInput();
		if (input instanceof CompareEditorInput) {
			CompareEditorInput ci = (CompareEditorInput) input;
			if (ci.getCompareResult() == null) {
				if (getState() == INITIALIZING) {
					getSite().setSelectionProvider(new CompareEditorSelectionProvider());
					setPageLater();
				} else if (getState() == STILL_INITIALIZING) {
					if (initializingPage == null) {
						initializingPage = getInitializingMessagePane(fPageBook);
					}
					fPageBook.showPage(initializingPage);
				} else if (getState() == CANCELED) {
					// Close the editor when we are canceled
					closeEditor();
				} else if (getState() == NO_DIFF) {
					// Prompt and close the editor as well
					setState(DONE);
					closeEditor();
					CompareUIPlugin.getDefault().handleNoDifference();
				} else if (getState() == ERROR) {
					// If an error occurred, close the editor
					// (the message would be displayed by the progress view)
					closeEditor();
				}
			} else if (fControl == null && getState() != CREATING_CONTROL) {
				if (getState() == CANCELED) {
					// Close the editor when we are canceled, even when compare
					// result has been already prepared
					closeEditor();
					return;
				}
				// Set the state in case this method gets called again
				setState(CREATING_CONTROL);
				if (getSite().getSelectionProvider() == null)
					getSite().setSelectionProvider(new CompareEditorSelectionProvider());
				try {
					fControl = ci.createContents(fPageBook);
				} catch (SWTException e) {
					// closed while creating
					if (e.code == SWT.ERROR_WIDGET_DISPOSED) {
						setState(CANCELED);
						return;
					}
				}
				fPageBook.showPage(fControl);
				PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl, ICompareContextIds.COMPARE_EDITOR);
				if (isActive()) {
					setFocus();
				}
				setState(INITIALIZED);
			}
		}
	}

	private boolean isActive() {
		return getSite().getPage().getActivePart() == this;
	}

	private void setPageLater() {
		Display.getCurrent().timerExec(1000, () -> {
			synchronized(CompareEditor.this) {
				if (getState() == INITIALIZING) {
					setState(STILL_INITIALIZING);
					createCompareControl();
				}
			}
		});
	}

	@Override
	public void dispose() {
		IEditorInput input= getEditorInput();
		if (input instanceof IPropertyChangeNotifier)
			((IPropertyChangeNotifier)input).removePropertyChangeListener(this);
		super.dispose();
	}

	@Override
	public void setFocus() {
		IEditorInput input= getEditorInput();
		if (input instanceof CompareEditorInput)
			if (!((CompareEditorInput)input).setFocus2())
				fPageBook.setFocus();
	}

	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	@Override
	public void doSaveAs() {
		Assert.isTrue(false); // Save As not supported for CompareEditor
	}

	@Override
	public void doSave(IProgressMonitor progressMonitor) {
		final IEditorInput input= getEditorInput();

		WorkspaceModifyOperation operation= new WorkspaceModifyOperation() {
			@Override
			public void execute(IProgressMonitor pm) throws CoreException {
				if (input instanceof CompareEditorInput)
					((CompareEditorInput)input).saveChanges(pm);
			}
		};

		Shell shell= getSite().getShell();

		try {
			operation.run(progressMonitor);
			firePropertyChange(PROP_DIRTY);
		} catch (InterruptedException x) {
			// NeedWork
		} catch (OperationCanceledException x) {
			// NeedWork
		} catch (InvocationTargetException x) {
			String title= Utilities.getString("CompareEditor.saveError.title"); //$NON-NLS-1$
			String reason= x.getTargetException().getMessage();
			MessageDialog.openError(shell, title, Utilities.getFormattedString("CompareEditor.cantSaveError", reason));	//$NON-NLS-1$
		}
	}

	@Override
	public boolean isDirty() {
		IEditorInput input= getEditorInput();
		if (input instanceof CompareEditorInput)
			return ((CompareEditorInput)input).isDirty();
		return false;
	}

	@Override
	public void propertyChange(PropertyChangeEvent event) {
		if (event.getProperty().equals(CompareEditorInput.DIRTY_STATE)) {
			Object old_value= event.getOldValue();
			Object new_value= event.getNewValue();
			if (old_value == null || new_value == null || !old_value.equals(new_value))
				firePropertyChange(PROP_DIRTY);
		} else if (event.getProperty().equals(CompareEditorInput.PROP_TITLE)) {
			setPartName(((CompareEditorInput)getEditorInput()).getTitle());
			setTitleToolTip(((CompareEditorInput)getEditorInput()).getToolTipText());
		} else if (event.getProperty().equals(CompareEditorInput.PROP_TITLE_IMAGE)) {
			setTitleImage(((CompareEditorInput)getEditorInput()).getTitleImage());
		}
	}

	@Override
	public Saveable[] getSaveables() {
		return internalGetSaveables(knownSaveables == null);
	}

	private Saveable[] internalGetSaveables(boolean init) {
		IEditorInput input= getEditorInput();
		Saveable[] sourceSaveables = getSaveables(input);
		if (init || knownSaveables == null) {
			recordSaveables(sourceSaveables);
		} else {
			for (int i = 0; i < sourceSaveables.length; i++) {
				Saveable saveable = sourceSaveables[i];
				if (!knownSaveables.contains(saveable)) {
					CompareUIPlugin.logErrorMessage(NLS.bind("Saveable {0} was not added using a saveables lifecycle event.", saveable.getName())); //$NON-NLS-1$
					knownSaveables.add(saveable);
				}
			}
			if (sourceSaveables.length != knownSaveables.size()) {
				CompareUIPlugin.logErrorMessage("Saveables were removed without an appropriate event"); //$NON-NLS-1$
				knownSaveables.clear();
				recordSaveables(sourceSaveables);
			}
		}
		return sourceSaveables;
	}

	private boolean isAllSaveablesKnown() {
		IEditorInput input= getEditorInput();
		Saveable[] sourceSaveables = getSaveables(input);
		if (knownSaveables == null) {
			return sourceSaveables.length == 0;
		}
		if (sourceSaveables.length != knownSaveables.size()) {
			return false;
		}
		for (int i = 0; i < sourceSaveables.length; i++) {
			Saveable saveable = sourceSaveables[i];
			if (!knownSaveables.contains(saveable)) {
				return false;
			}
		}
		return true;
	}

	private void recordSaveables(Saveable[] sourceSaveables) {
		if (knownSaveables == null)
			knownSaveables = new HashSet<>();
		Collections.addAll(knownSaveables, sourceSaveables);
	}

	private Saveable[] getSaveables(IEditorInput input) {
		if (input instanceof ISaveablesSource) {
			ISaveablesSource source= (ISaveablesSource) input;
			return source.getSaveables();
		}
		return new Saveable[] { getSaveable() };
	}

	private Saveable getSaveable() {
		if (fSaveable == null) {
			fSaveable= new CompareSaveable();
		}
		return fSaveable;
	}

	@Override
	public Saveable[] getActiveSaveables() {
		IEditorInput input= getEditorInput();
		if (input instanceof ISaveablesSource) {
			ISaveablesSource source= (ISaveablesSource) input;
			return source.getActiveSaveables();
		}
		return new Saveable[] { getSaveable() };
	}

	private class CompareSaveable extends Saveable {

		@Override
		public String getName() {
			return CompareEditor.this.getPartName();
		}

		@Override
		public String getToolTipText() {
			return CompareEditor.this.getTitleToolTip();
		}

		@Override
		public ImageDescriptor getImageDescriptor() {
			return ImageDescriptor.createFromImage(CompareEditor.this.getTitleImage());
		}

		@Override
		public void doSave(IProgressMonitor monitor) throws CoreException {
			CompareEditor.this.doSave(monitor);
		}

		@Override
		public boolean isDirty() {
			return CompareEditor.this.isDirty();
		}

		@Override
		public boolean equals(Object object) {
			return object == this;
		}

		@Override
		public int hashCode() {
			return CompareEditor.this.hashCode();
		}
	}

	private Composite getInitializingMessagePane(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setBackground(getBackgroundColor(parent));
		GridLayout layout = new GridLayout();
		layout.numColumns = 3;
		composite.setLayout(layout);

		createDescriptionLabel(composite, CompareMessages.CompareEditor_1);
		return composite;
	}

	private Color getBackgroundColor(Composite parent) {
		return parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
	}

	private Label createDescriptionLabel(Composite parent, String text) {
		Label description = new Label(parent, SWT.WRAP);
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		data.horizontalSpan = 2;
		description.setLayoutData(data);
		description.setText(text);
		description.setBackground(getBackgroundColor(parent));
		return description;
	}

	private void closeEditor() {
		getSite().getPage().closeEditor(CompareEditor.this, false);
	}

	private synchronized void setState(int state) {
		this.state = state;
	}

	private int getState() {
		return state;
	}

	@Override
	public void handleLifecycleEvent(SaveablesLifecycleEvent event) {
		ISaveablesLifecycleListener lifecycleListener=
				getSite().getService(ISaveablesLifecycleListener.class);
		if (event.getEventType() == SaveablesLifecycleEvent.POST_CLOSE) {
			// We may get a post close for a saveable that is not known to the workbench.
			// Only pass on the event for known saveables
			if (knownSaveables == null || knownSaveables.isEmpty())
				return;
			java.util.List<Saveable> result = new ArrayList<>();
			Saveable[] all = event.getSaveables();
			for (int i = 0; i < all.length; i++) {
				Saveable saveable = all[i];
				if (knownSaveables.contains(saveable))
					result.add(saveable);
					knownSaveables.remove(saveable);
			}
			if (result.isEmpty())
				return;
			event = new SaveablesLifecycleEvent(this,
					SaveablesLifecycleEvent.POST_CLOSE,
					result.toArray(new Saveable[result.size()]),
					false);
		} else if (event.getEventType() == SaveablesLifecycleEvent.POST_OPEN) {
			recordSaveables(event.getSaveables());
		}
		lifecycleListener.handleLifecycleEvent(event);
	}
}
