/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Stefan Xenos, IBM; Chris Torrence, ITT Visual Information Solutions - bug 51580
 *     Nikolay Botev - bug 240651
 *     Andrey Loskutov <loskutov@gmx.de> - Bug 372799
 *     Daniel Kruegler <daniel.kruegler@gmail.com> - Bug 495940
 *******************************************************************************/
package org.eclipse.ui.internal;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
import org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.ISizeProvider;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPart2;
import org.eclipse.ui.IWorkbenchPart3;
import org.eclipse.ui.IWorkbenchPartConstants;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.e4.compatibility.CompatibilityPart;
import org.eclipse.ui.internal.misc.UIListenerLogging;
import org.eclipse.ui.internal.util.Util;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

/**
 *
 */
public abstract class WorkbenchPartReference implements IWorkbenchPartReference, ISizeProvider {

	/**
	 * Internal property ID: Indicates that the underlying part was created
	 */
	public static final int INTERNAL_PROPERTY_OPENED = 0x211;

	/**
	 * Internal property ID: Indicates that the underlying part was destroyed
	 */
	public static final int INTERNAL_PROPERTY_CLOSED = 0x212;

	/**
	 * Internal property ID: Indicates that the result of
	 * IEditorReference.isPinned()
	 */
	public static final int INTERNAL_PROPERTY_PINNED = 0x213;

	/**
	 * Internal property ID: Indicates that the result of getVisible() has changed
	 */
	public static final int INTERNAL_PROPERTY_VISIBLE = 0x214;

	/**
	 * Internal property ID: Indicates that the result of isZoomed() has changed
	 */
	public static final int INTERNAL_PROPERTY_ZOOMED = 0x215;

	/**
	 * Internal property ID: Indicates that the part has an active child and the
	 * active child has changed. (fired by PartStack)
	 */
	public static final int INTERNAL_PROPERTY_ACTIVE_CHILD_CHANGED = 0x216;

	/**
	 * Internal property ID: Indicates that changed in the min / max state has
	 * changed
	 */
	public static final int INTERNAL_PROPERTY_MAXIMIZED = 0x217;

	// State constants //////////////////////////////

	/**
	 * State constant indicating that the part is not created yet
	 */
	public static int STATE_LAZY = 0;

	/**
	 * State constant indicating that the part is in the process of being created
	 */
	public static int STATE_CREATION_IN_PROGRESS = 1;

	/**
	 * State constant indicating that the part has been created
	 */
	public static int STATE_CREATED = 2;

	/**
	 * State constant indicating that the reference has been disposed (the reference
	 * shouldn't be used anymore)
	 */
	public static int STATE_DISPOSED = 3;

	static String MEMENTO_KEY = "memento"; //$NON-NLS-1$

	/**
	 * Current state of the reference. Used to detect recursive creation errors,
	 * disposed references, etc.
	 */
	private int state = STATE_LAZY;

	protected IWorkbenchPart legacyPart;
	private boolean pinned = false;

	/**
	 * API listener list
	 */
	private ListenerList<IPropertyListener> propChangeListeners = new ListenerList<>();

	/**
	 * Internal listener list. Listens to the INTERNAL_PROPERTY_* property change
	 * events that are not yet API. TODO: Make these properties API in 3.2
	 */
	private ListenerList<IPropertyListener> internalPropChangeListeners = new ListenerList<>();

	private ListenerList<IPropertyChangeListener> partChangeListeners = new ListenerList<>();

	protected Map<String, String> propertyCache = new HashMap<>();

	private IPropertyListener propertyChangeListener = this::partPropertyChanged;

	private IPropertyChangeListener partPropertyChangeListener = this::partPropertyChanged;

	private IWorkbenchPage page;

	private MPart part;

	private IEclipseContext windowContext;

	private EventHandler contextEventHandler;

	public WorkbenchPartReference(IEclipseContext windowContext, IWorkbenchPage page, MPart part) {
		this.windowContext = windowContext;
		this.page = page;
		this.part = part;

		// cache the reference in the MPart's transientData
		if (part != null) {
			part.getTransientData().put(IWorkbenchPartReference.class.getName(), this);
		}
	}

	private EventHandler createContextEventHandler() {
		if (contextEventHandler == null) {
			contextEventHandler = this::handleContextSet;
		}
		return contextEventHandler;
	}

	private void handleContextSet(Event event) {
		Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
		MPart part = getModel();
		if (element == part) {
			IEclipseContext context = part.getContext();
			if (context != null) {
				context.set(getClass().getName(), this);
				unsubscribe();
			}
		}
	}

	public void subscribe() {
		IEventBroker broker = windowContext.get(IEventBroker.class);
		broker.subscribe(UIEvents.Context.TOPIC_CONTEXT, createContextEventHandler());
	}

	public void unsubscribe() {
		if (contextEventHandler != null) {
			IEventBroker broker = windowContext.get(IEventBroker.class);
			broker.unsubscribe(contextEventHandler);
			contextEventHandler = null;
		}
	}

	public boolean isDisposed() {
		return state == STATE_DISPOSED;
	}

	protected void checkReference() {
		if (state == STATE_DISPOSED) {
			throw new RuntimeException("Error: IWorkbenchPartReference disposed"); //$NON-NLS-1$
		}
	}

	public MPart getModel() {
		return part;
	}

	protected void partPropertyChanged(Object source, int propId) {
		firePropertyChange(propId);

		// Let the model manager know as well
		if (propId == IWorkbenchPartConstants.PROP_DIRTY) {
			IWorkbenchPart actualPart = getPart(false);
			if (actualPart != null) {
				SaveablesList modelManager = (SaveablesList) actualPart.getSite()
						.getService(ISaveablesLifecycleListener.class);
				modelManager.dirtyChanged(actualPart);
			}
		}
	}

	protected void partPropertyChanged(PropertyChangeEvent event) {
		firePartPropertyChange(event);
	}

	/**
	 * Releases any references maintained by this part reference when its actual
	 * part becomes known (not called when it is disposed).
	 */
	protected void releaseReferences() {

	}

	/* package */ void addInternalPropertyListener(IPropertyListener listener) {
		internalPropChangeListeners.add(listener);
	}

	/* package */ void removeInternalPropertyListener(IPropertyListener listener) {
		internalPropChangeListeners.remove(listener);
	}

	protected void fireInternalPropertyChange(int id) {
		for (IPropertyListener listener : internalPropChangeListeners) {
			listener.propertyChanged(this, id);
		}
	}

	/**
	 * @see IWorkbenchPart
	 */
	@Override
	public void addPropertyListener(IPropertyListener listener) {
		// The properties of a disposed reference will never change, so don't
		// add listeners
		if (isDisposed()) {
			return;
		}

		propChangeListeners.add(listener);
	}

	/**
	 * @see IWorkbenchPart
	 */
	@Override
	public void removePropertyListener(IPropertyListener listener) {
		// Currently I'm not calling checkReference here for fear of breaking things
		// late in 3.1, but it may
		// make sense to do so later. For now we just turn it into a NOP if the
		// reference is disposed.
		if (isDisposed()) {
			return;
		}
		propChangeListeners.remove(listener);
	}

	@Override
	public String getTitle() {
		String title = legacyPart == null ? part.getLocalizedLabel() : legacyPart.getTitle();
		return Util.safeString(title);
	}

	@Override
	public String getTitleToolTip() {
		String toolTip = (String) part.getTransientData().get(IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY);
		if (toolTip == null || toolTip.isEmpty())
			toolTip = part.getLocalizedTooltip();
		return Util.safeString(toolTip);
	}

	@Override
	public String getId() {
		String id = part.getElementId();

		// Only return the descriptor id
		int colonIndex = id.indexOf(':');
		return colonIndex == -1 ? id : id.substring(0, colonIndex);
	}

	/**
	 * Computes a new title for the part. Subclasses may override to change the
	 * default behavior.
	 *
	 * @return the title for the part
	 */
	protected String computeTitle() {
		return getRawTitle();
	}

	/**
	 * Returns the unmodified title for the part, or the empty string if none
	 *
	 * @return the unmodified title, as set by the IWorkbenchPart. Returns the empty
	 *         string if none.
	 */
	protected final String getRawTitle() {
		return Util.safeString(legacyPart.getTitle());
	}

	@Override
	public final Image getTitleImage() {
		if (isDisposed()) {
			return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_DEF_VIEW);
		}

		WorkbenchWindow wbw = (WorkbenchWindow) PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		if (part != null && wbw.getModel().getRenderer() instanceof SWTPartRenderer) {
			SWTPartRenderer r = (SWTPartRenderer) wbw.getModel().getRenderer();
			Image image = r.getImage(part);
			if (image != null) {
				return image;
			}
		}

		return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_DEF_VIEW);
	}

	/* package */ void fireVisibilityChange() {
		fireInternalPropertyChange(INTERNAL_PROPERTY_VISIBLE);
	}

	/* package */ void fireZoomChange() {
		fireInternalPropertyChange(INTERNAL_PROPERTY_ZOOMED);
	}

	protected void firePropertyChange(int id) {
		immediateFirePropertyChange(id);
	}

	private void immediateFirePropertyChange(int id) {
		UIListenerLogging.logPartReferencePropertyChange(this, id);
		for (IPropertyListener listener : propChangeListeners) {
			listener.propertyChanged(legacyPart, id);
		}

		fireInternalPropertyChange(id);
	}

	public abstract PartSite getSite();

	public abstract void initialize(IWorkbenchPart part) throws PartInitException;

	void addPropertyListeners() {
		IWorkbenchPart workbenchPart = getPart(false);
		if (workbenchPart != null) {
			workbenchPart.addPropertyListener(propertyChangeListener);

			if (workbenchPart instanceof IWorkbenchPart3) {
				((IWorkbenchPart3) workbenchPart).addPartPropertyListener(partPropertyChangeListener);

			}
		}
	}

	@Override
	public final IWorkbenchPart getPart(boolean restore) {
		if (isDisposed()) {
			return null;
		}

		if (legacyPart == null) {
			if (restore && part.getWidget() == null) {
				// create the underlying client object backed by the part model
				// with the rendering engine
				EPartService partService = windowContext.get(EPartService.class);
				partService.showPart(part, PartState.CREATE);
			}

			// check if we were actually created, it is insufficient to check
			// whether the 'object' feature is valid or not because it is one of
			// the last things to be unset during the teardown process, this
			// means we may return a valid workbench part even if it is actually
			// in the process of being destroyed, see bug 328944
			if (part.getObject() instanceof CompatibilityPart) {
				CompatibilityPart compatibilityPart = (CompatibilityPart) part.getObject();
				if (compatibilityPart != null) {
					legacyPart = compatibilityPart.getPart();
				}
			} else if (part.getObject() != null) {
				if (part.getTransientData().get(E4PartWrapper.E4_WRAPPER_KEY) instanceof E4PartWrapper) {
					return (IWorkbenchPart) part.getTransientData().get(E4PartWrapper.E4_WRAPPER_KEY);
				}
			}
		}

		return legacyPart;
	}

	public abstract IWorkbenchPart createPart() throws PartInitException;

	abstract IWorkbenchPart createErrorPart();

	public abstract IWorkbenchPart createErrorPart(IStatus status);

	protected void doDisposeNestedParts() {
		// To be implemented by subclasses
	}

	/**
	 *
	 */
	private void doDisposePart() {
		if (legacyPart != null) {
			fireInternalPropertyChange(INTERNAL_PROPERTY_CLOSED);
			// Don't let exceptions in client code bring us down. Log them and continue.
			try {
				legacyPart.removePropertyListener(propertyChangeListener);
				if (legacyPart instanceof IWorkbenchPart3) {
					((IWorkbenchPart3) legacyPart).removePartPropertyListener(partPropertyChangeListener);
				}
			} catch (Exception e) {
				WorkbenchPlugin.log(e);
			}
			legacyPart = null;
		}
	}

	public void setPinned(boolean newPinned) {
		if (isDisposed()) {
			return;
		}

		if (newPinned == pinned) {
			return;
		}

		pinned = newPinned;

		immediateFirePropertyChange(IWorkbenchPartConstants.PROP_TITLE);
		if (pinned)
			part.getTags().add(IPresentationEngine.ADORNMENT_PIN);
		else
			part.getTags().remove(IPresentationEngine.ADORNMENT_PIN);

		fireInternalPropertyChange(INTERNAL_PROPERTY_PINNED);
	}

	public boolean isPinned() {
		return pinned;
	}

	@Override
	public String getPartProperty(String key) {
		if (legacyPart != null) {
			if (legacyPart instanceof IWorkbenchPart3) {
				return ((IWorkbenchPart3) legacyPart).getPartProperty(key);
			}
		} else {
			return propertyCache.get(key);
		}
		return null;
	}

	@Override
	public void addPartPropertyListener(IPropertyChangeListener listener) {
		if (isDisposed()) {
			return;
		}
		partChangeListeners.add(listener);
	}

	@Override
	public void removePartPropertyListener(IPropertyChangeListener listener) {
		if (isDisposed()) {
			return;
		}
		partChangeListeners.remove(listener);
	}

	protected void firePartPropertyChange(PropertyChangeEvent event) {
		for (IPropertyChangeListener l : partChangeListeners) {
			l.propertyChange(event);
		}
	}

	protected void createPartProperties(IWorkbenchPart3 workbenchPart) {
		Iterator<Entry<String, String>> i = propertyCache.entrySet().iterator();
		while (i.hasNext()) {
			Entry<String, String> e = i.next();
			workbenchPart.setPartProperty(e.getKey(), e.getValue());
		}
	}

	@Override
	public int computePreferredSize(boolean width, int availableParallel, int availablePerpendicular,
			int preferredResult) {

		ISizeProvider sizeProvider = Adapters.adapt(legacyPart, ISizeProvider.class);
		if (sizeProvider != null) {
			return sizeProvider.computePreferredSize(width, availableParallel, availablePerpendicular, preferredResult);
		}

		return preferredResult;
	}

	@Override
	public int getSizeFlags(boolean width) {
		ISizeProvider sizeProvider = Adapters.adapt(legacyPart, ISizeProvider.class);
		if (sizeProvider != null) {
			return sizeProvider.getSizeFlags(width);
		}
		return 0;
	}

	@Override
	public IWorkbenchPage getPage() {
		return page;
	}

	public void setPage(IWorkbenchPage newPage) {
		page = newPage;
	}

	@Override
	public String getPartName() {
		return part.getLocalizedLabel();
	}

	@Override
	public String getContentDescription() {
		IWorkbenchPart workbenchPart = getPart(false);
		if (workbenchPart instanceof IWorkbenchPart2) {
			return ((IWorkbenchPart2) workbenchPart).getContentDescription();
		}
		return workbenchPart.getTitle();
	}

	@Override
	public boolean isDirty() {
		IWorkbenchPart part = getPart(false);
		ISaveablePart saveable = SaveableHelper.getSaveable(part);
		if (saveable != null) {
			return saveable.isDirty();
		}
		return false;
	}

	public void invalidate() {
		doDisposePart();
	}

	public final PartPane getPane() {
		return new PartPane() {
			@Override
			public Control getControl() {
				return part == null ? null : (Control) part.getWidget();
			}
		};
	}
}
