/*******************************************************************************
 * Copyright (c) 2009, 2014 IBM Corporation and others.
 * All rights reserved. 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
 *     Tristan Hume - <trishume@gmail.com> -
 *     		Fix for Bug 2369 [Workbench] Would like to be able to save workspace without exiting
 *     		Implemented workbench auto-save to correctly restore state in case of crash.
 *     Terry Parker <tparker@google.com> - Bug 416673
 *     Florian Pirchner - adjusted for Vaaclipse usecases - uses different ModelAssembler and ModelUtils
 ******************************************************************************/

package org.eclipse.osbp.vaaclipse.addons.common.resource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;

import org.eclipse.core.internal.runtime.PlatformURLPluginConnection;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.ui.internal.workbench.CommandLineOptionModelProcessor;
import org.eclipse.e4.ui.internal.workbench.E4Workbench;
import org.eclipse.e4.ui.internal.workbench.E4XMIResource;
import org.eclipse.e4.ui.internal.workbench.URIHelper;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.MApplicationElement;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement;
import org.eclipse.e4.ui.workbench.IWorkbench;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.osbp.vaaclipse.addons.common.api.resource.ICustomizedModelResourceHandler;
import org.eclipse.osgi.service.datalocation.Location;
import org.osgi.framework.Bundle;

/**
 * A common implementation for the ResourceHandler. This resource handler
 * automatically loads user defined perspectives from a different model. So user
 * can save, create and delete their own perspectives.
 */
@SuppressWarnings("restriction")
public class ResourceHandler implements ICustomizedModelResourceHandler {

	/** The resource set. */
	@Inject
	private ResourceSet resourceSet;

	/** The resource. */
	private E4XMIResource resource;

	/** The logger. */
	@Inject
	private Logger logger;

	/** The user id. */
	@Inject
	@Named("userId")
	@Optional
	String userId;

	/** The context. */
	@Inject
	private IEclipseContext context;

	/** The application definition instance. */
	@Inject
	@Named(E4Workbench.INITIAL_WORKBENCH_MODEL_URI)
	private URI applicationDefinitionInstance;

	/** The instance location. */
	@Inject
	@Optional
	@Named(E4Workbench.INSTANCE_LOCATION)
	private Location instanceLocation;

	/**
	 * Dictates whether the model should be stored using EMF or with the merging
	 * algorithm. https://bugs.eclipse.org/bugs/show_bug.cgi?id=295524
	 * 
	 */
	final private boolean saveAndRestore;
	
	/** The clear persisted state. */
	private boolean clearPersistedState;

	/**
	 * Constructor.
	 *
	 * @param saveAndRestore
	 *            the save and restore
	 * @param clearPersistedState
	 *            the clear persisted state
	 */
	@Inject
	public ResourceHandler(
			@Named(IWorkbench.PERSIST_STATE) boolean saveAndRestore,
			@Named(IWorkbench.CLEAR_PERSISTED_STATE) boolean clearPersistedState) {
		this.saveAndRestore = saveAndRestore;
		this.clearPersistedState = clearPersistedState;
	}

	/**
	 * Inits the.
	 */
	@PostConstruct
	void init() {

	}

	/**
	 * Checks for top level windows.
	 *
	 * @return {@code true} if the current application model has top-level
	 *         windows.
	 */
	public boolean hasTopLevelWindows() {
		return hasTopLevelWindows(resource);
	}

	/**
	 * Checks for top level windows.
	 *
	 * @param applicationResource
	 *            the application resource
	 * @return {@code true} if the specified application model has top-level
	 *         windows.
	 */
	private boolean hasTopLevelWindows(Resource applicationResource) {
		if (applicationResource == null
				|| applicationResource.getContents() == null) {
			// If the application resource doesn't exist or has no contents,
			// then it has no
			// top-level windows (and we are in an error state).
			return false;
		}
		MApplication application = (MApplication) applicationResource
				.getContents().get(0);
		return !application.getChildren().isEmpty();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.e4.ui.workbench.IModelResourceHandler#loadMostRecentModel()
	 */
	@Override
	public Resource loadMostRecentModel() {
		File workbenchData = null;
		URI restoreLocation = null;

		if (saveAndRestore) {
			workbenchData = getWorkbenchSaveLocation();
			restoreLocation = URI
					.createFileURI(workbenchData.getAbsolutePath());
		}

		if (clearPersistedState && workbenchData != null
				&& workbenchData.exists()) {
			workbenchData.delete();
		}

		// last stored time-stamp
		long restoreLastModified = restoreLocation == null ? 0L : new File(
				restoreLocation.toFileString()).lastModified();

		// See bug 380663, bug 381219
		// long lastApplicationModification = getLastApplicationModification();
		// boolean restore = restoreLastModified > lastApplicationModification;
		boolean restore = restoreLastModified > 0;
		boolean initialModel;

		resource = null;
		if (restore && saveAndRestore) {
			resource = (E4XMIResource) loadResource(restoreLocation);
			// If the saved model does not have any top-level windows, Eclipse
			// will exit
			// immediately, so throw out the persisted state and reinitialize
			// with the defaults.
			if (!hasTopLevelWindows(resource)) {
				if (logger != null) {
					logger.error(
							new Exception(), // log a stack trace to help debug
												// the corruption
							"The persisted workbench has no top-level windows, so reinitializing with defaults."); //$NON-NLS-1$
				}
				resource = null;
			}
		}
		if (resource == null) {
			Resource appResource = loadResource(applicationDefinitionInstance);
			if (!hasTopLevelWindows(appResource) && logger != null) {
				logger.error(
						new Exception(), // log a stack trace to help debug the
											// corruption
						"Initializing from the application definition instance yields no top-level windows! " //$NON-NLS-1$
								+ "Continuing execution, but the missing windows may cause other initialization failures."); //$NON-NLS-1$
			}
			MApplication theApp = (MApplication) appResource.getContents().get(
					0);
			resource = (E4XMIResource) createResourceWithApp(theApp);
			context.set(E4Workbench.NO_SAVED_MODEL_FOUND, Boolean.TRUE);
			initialModel = true;

			// remove the appResource since it was damaged by
			// #createResourceWithApp()
			appResource.unload();
			resourceSet.getResources().remove(appResource);
		} else {
			initialModel = false;
		}

		// create an URI mapping from the application resource to the user
		// resource
		resourceSet.getURIConverter().getURIMap()
				.put(applicationDefinitionInstance, resource.getURI());
		// create a relative URI mapping for the last segment of the resource
		// URI to its full qualified URI.
		// Necessary to load split models like an exported perspective
		resourceSet
				.getURIConverter()
				.getURIMap()
				.put(URI.createURI(resource.getURI().lastSegment()),
						resource.getURI());

		// Add model items described in the model extension point
		// This has to be done before commands are put into the context
		MApplication appElement = (MApplication) resource.getContents().get(0);
		Map<String, String> weights = getWeights(resource, appElement);
		this.context.set(MApplication.class, appElement);
		VaaclipseModelAssembler contribProcessor = ContextInjectionFactory
				.make(VaaclipseModelAssembler.class, context);
		contribProcessor.processModel(initialModel);

		// load the customized models
		//
		SystemuserModelHandler handler = ContextInjectionFactory.make(
				SystemuserModelHandler.class, context);
		handler.mergeFragment();

		if (!clearPersistedState) {
			CommandLineOptionModelProcessor processor = ContextInjectionFactory
					.make(CommandLineOptionModelProcessor.class, context);
			processor.process();
		}

		// apply the weights
		//
		for (Map.Entry<String, String> entry : weights.entrySet()) {
			MUIElement element = (MUIElement) resource.getIDToEObjectMap().get(
					entry.getKey());
			if (element != null) {
				element.setContainerData(entry.getValue());
			}
		}

		return resource;
	}

	/**
	 * Returns the layout weights for later restore.
	 *
	 * @param resource
	 *            the resource
	 * @param appElement
	 *            the app element
	 * @return the weights
	 */
	private Map<String, String> getWeights(E4XMIResource resource,
			MApplication appElement) {

		Map<String, String> result = new HashMap<String, String>();
		TreeIterator<EObject> treeIt = EcoreUtil.getAllContents(
				(EObject) appElement, true);
		while (treeIt.hasNext()) {
			EObject eObj = treeIt.next();
			if (eObj instanceof MUIElement) {
				result.put(resource.getID(eObj),
						((MUIElement) eObj).getContainerData());
			}
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.e4.ui.workbench.IModelResourceHandler#save()
	 */
	@Override
	public void save() throws IOException {
		if (saveAndRestore) {
			MApplication mApp = (MApplication) resource.getContents().get(0);
			Resource toSave = createResourceForSave(mApp);
			toSave.save(null);
			// resource.save(null);
		}
	}

	/**
	 * Creates a resource with an app Model, used for saving copies of the main
	 * app model.
	 * 
	 * @param theApp
	 *            the application model to add to the resource
	 * @return a resource with a proper save path with the model as contents
	 */
	@Override
	public Resource createResourceWithApp(MApplication theApp) {
		E4XMIResource appResource = (E4XMIResource) ((EObject) theApp)
				.eResource();
		Map<EObject, String> idMap = new HashMap<EObject, String>(
				appResource.getEObjectToIDMap());

		E4XMIResource res = (E4XMIResource) createResource();
		// Removes the app model from the appResource
		res.getContents().add((EObject) theApp);

		// replace the IDs for the different EObjects by their original values.
		// Otherwise proxies can not be resolved.
		TreeIterator<EObject> it = EcoreUtil.getAllContents(res.getContents());
		while (it.hasNext()) {
			EObject o = it.next();
			res.setID(o, idMap.get(o));
		}

		return res;
	}

	/**
	 * Creates a resource for saving issues. The content MApplication will be
	 * prepared. All the elements tagged with "vaaclipse-transient" will be
	 * removed from the model before saving.
	 * 
	 * @param theApp
	 *            the application model to add to the resource
	 * @return a resource with a proper save path with the model as contents
	 */
	protected Resource createResourceForSave(MApplication theApp) {
		E4XMIResource originalResource = (E4XMIResource) ((EObject) theApp)
				.eResource();

		// create a new resource with the copied application model and same URI
		//
		E4XMIResource toSaveResource = (E4XMIResource) createResource();
		toSaveResource.setURI(originalResource.getURI());

		// copy the eObject
		//
		EcoreUtil.Copier copier = new EcoreUtil.Copier();
		EObject copyApp = copier.copy((EObject) theApp);
		copier.copyReferences();

		// Removes all transient objects
		//
		removeTransientObjects(copyApp);

		// set the copy to the new resource
		//
		toSaveResource.getContents().add(copyApp);

		// the xml ids to be transferred to the new resource
		//
		Map<EObject, String> idMap = new HashMap<EObject, String>(
				originalResource.getEObjectToIDMap());

		// replace the IDs for the different EObjects by their original values.
		// Otherwise proxies can not be resolved.
		//
		TreeIterator<EObject> originalIterator = EcoreUtil
				.getAllContents(originalResource.getContents());
		while (originalIterator.hasNext()) {
			EObject original = originalIterator.next();

			String id = idMap.get(original);
			// use the copier to find the copied element for the original
			toSaveResource.setID(copier.get(original), id);
		}

		return toSaveResource;
	}

	/**
	 * Remove all transient objects and its cross references.
	 *
	 * @param copyApp
	 *            the copy app
	 */
	private void removeTransientObjects(EObject copyApp) {
		List<EObject> toRemove = new ArrayList<>();
		TreeIterator<EObject> iterator = EcoreUtil.getAllContents(copyApp,
				false);
		while (iterator.hasNext()) {
			EObject eObject = iterator.next();
			if (eObject instanceof MUIElement) {
				MUIElement uiElement = (MUIElement) eObject;
				if (uiElement.getTags().contains("vaaclipse-transient")) {
					toRemove.add(eObject);
				}
			}
		}

		for (EObject eObject : toRemove) {
			// remove the eObject
			EcoreUtil.remove(eObject);

			// remove all cross references
			Collection<Setting> usages = EcoreUtil.UsageCrossReferencer.find(
					eObject, copyApp);
			for (Setting setting : usages) {
				setting.unset();
			}
		}

	}

	/**
	 * Creates the resource.
	 *
	 * @return the resource
	 */
	private Resource createResource() {
		// if (saveAndRestore) {
		URI saveLocation = URI.createFileURI(getWorkbenchSaveLocation()
				.getAbsolutePath());
		return resourceSet.createResource(saveLocation);
		// }
		//		return resourceSet.createResource(URI.createURI("workbench.xmi")); //$NON-NLS-1$
	}

	/**
	 * Gets the workbench save location.
	 *
	 * @return the workbench save location
	 */
	private File getWorkbenchSaveLocation() {
		File workbenchData = new File(getBaseLocation(), String.format(
				"%s_workbench.xmi", userId)); //$NON-NLS-1$
		return workbenchData;
	}

	/**
	 * Gets the base location.
	 *
	 * @return the base location
	 */
	private File getBaseLocation() {
		File baseLocation;
		try {
			baseLocation = new File(URIUtil.toURI(instanceLocation.getURL()));
		} catch (URISyntaxException e) {
			throw new RuntimeException(e);
		}
		baseLocation = new File(baseLocation, ".metadata"); //$NON-NLS-1$
		baseLocation = new File(baseLocation, ".plugins"); //$NON-NLS-1$
		baseLocation = new File(baseLocation, "org.eclipse.e4.workbench"); //$NON-NLS-1$
		return baseLocation;
	}

	/**
	 * Load resource.
	 *
	 * @param uri
	 *            the uri
	 * @return the resource
	 */
	// Ensures that even models with error are loaded!
	private Resource loadResource(URI uri) {
		Resource resource;
		try {
			resource = getResource(uri);
		} catch (Exception e) {
			// TODO We could use diagnostics for better analyzing the error
			logger.error(e, "Unable to load resource " + uri.toString()); //$NON-NLS-1$
			return null;
		}

		// TODO once we switch from deltas, we only need this once on the
		// default model?
		String contributorURI = URIHelper.EMFtoPlatform(uri);
		if (contributorURI != null) {
			TreeIterator<EObject> it = EcoreUtil.getAllContents(resource
					.getContents());
			while (it.hasNext()) {
				EObject o = it.next();
				if (o instanceof MApplicationElement) {
					((MApplicationElement) o).setContributorURI(contributorURI);
				}
			}
		}
		return resource;
	}

	/**
	 * Gets the resource.
	 *
	 * @param uri
	 *            the uri
	 * @return the resource
	 * @throws Exception
	 *             the exception
	 */
	private Resource getResource(URI uri) throws Exception {
		Resource resource;
		if (saveAndRestore) {
			resource = resourceSet.getResource(uri, true);
		} else {
			// Workaround for java.lang.IllegalStateException: No instance data
			// can be specified
			// thrown by
			// org.eclipse.core.internal.runtime.DataArea.assertLocationInitialized
			// The DataArea.assertLocationInitialized is called by
			// ResourceSetImpl.getResource(URI,
			// boolean)
			resource = resourceSet.createResource(uri);
			resource.load(new URL(uri.toString()).openStream(),
					resourceSet.getLoadOptions());
		}

		return resource;
	}

	/**
	 * Gets the last application modification.
	 *
	 * @return the last application modification
	 */
	protected long getLastApplicationModification() {
		long appLastModified = 0L;
		ResourceSetImpl resourceSetImpl = new ResourceSetImpl();

		Map<String, ?> attributes = resourceSetImpl
				.getURIConverter()
				.getAttributes(
						applicationDefinitionInstance,
						Collections
								.singletonMap(
										URIConverter.OPTION_REQUESTED_ATTRIBUTES,
										Collections
												.singleton(URIConverter.ATTRIBUTE_TIME_STAMP)));

		Object timestamp = attributes.get(URIConverter.ATTRIBUTE_TIME_STAMP);
		if (timestamp instanceof Long) {
			appLastModified = ((Long) timestamp).longValue();
		} else if (applicationDefinitionInstance.isPlatformPlugin()) {
			try {
				java.net.URL url = new java.net.URL(
						applicationDefinitionInstance.toString());
				// can't just use 'url.openConnection()' as it usually returns a
				// PlatformURLPluginConnection which doesn't expose the
				// last-modification time. So we try to resolve the file through
				// the bundle to obtain a BundleURLConnection instead.
				Object[] obj = PlatformURLPluginConnection.parse(url.getFile()
						.trim(), url);
				Bundle b = (Bundle) obj[0];
				// first try to resolve as an bundle file entry, then as a
				// resource using
				// the bundle's classpath
				java.net.URL resolved = b.getEntry((String) obj[1]);
				if (resolved == null) {
					resolved = b.getResource((String) obj[1]);
				}
				if (resolved != null) {
					URLConnection openConnection = resolved.openConnection();
					appLastModified = openConnection.getLastModified();
				}
			} catch (Exception e) {
				// ignore
			}
		}

		return appLastModified;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.vaaclipse.addons.common.api.resource.ICustomizedModelResourceHandler#loadPerspective(java.io.InputStream)
	 */
	@Override
	public MPerspective loadPerspective(InputStream stream) throws IOException {
		E4XMIResource resource = new E4XMIResource(URI.createURI("perspective"));
		resource.load(stream, null);
		
		final MPerspective perspective = (MPerspective) resource.getContents()
				.get(0);
		
		EObject result = EcoreUtil.copy((EObject) perspective);

		resource.unload();
		
		return (MPerspective) result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.vaaclipse.addons.common.api.resource.ICustomizedModelResourceHandler#savePerspective(org.eclipse.e4.ui.model.application.ui.advanced.MPerspective)
	 */
	@Override
	public void savePerspective(MPerspective perspective) throws IOException {
		Resource resource = createResourceForSave(perspective);
		resource.save(null);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.osbp.vaaclipse.addons.common.api.resource.ICustomizedModelResourceHandler#savePerspective(java.io.OutputStream, org.eclipse.e4.ui.model.application.ui.advanced.MPerspective)
	 */
	@Override
	public void savePerspective(OutputStream stream, MPerspective perspective) throws IOException {
		Resource resource = createResourceForSave(perspective);
		resource.save(stream, null);
	}

	/**
	 * Creates a resource for saving issues. The content {@link MPerspective}
	 * will be prepared. All the elements tagged with "vaaclipse-transient" will
	 * be removed from the model before saving.
	 *
	 * @param perspective
	 *            the perspective
	 * @return a resource with a proper save path with the model as contents
	 */
	protected Resource createResourceForSave(MPerspective perspective) {
		// create a new resource with the copied application model and same URI
		//
		URI saveLocation = URI
				.createFileURI(getWorkbenchSaveLocation().getAbsolutePath())
				.trimSegments(1).appendSegment(perspective.getElementId())
				.appendFileExtension("perspective");
		XMIResource toSaveResource = new XMIResourceImpl(saveLocation);

		// copy the eObject
		//
		EcoreUtil.Copier copier = new EcoreUtil.Copier();
		EObject copyPerspective = copier.copy((EObject) perspective);
		copier.copyReferences();
		

		// Removes all transient objects
		//
		removeTransientObjects(copyPerspective);
		
		// remove dangling refs
		removeDanglingRefs((MPerspective) copyPerspective);

		// set the copy to the new resource
		//
		toSaveResource.getContents().add(copyPerspective);

		// // the xml ids to be transferred to the new resource
		// //
		// Map<EObject, String> idMap = new HashMap<EObject, String>(
		// originalResource.getEObjectToIDMap());
		//
		// // replace the IDs for the different EObjects by their original
		// values.
		// // Otherwise proxies can not be resolved.
		// //
		// TreeIterator<EObject> originalIterator = EcoreUtil
		// .getAllContents(originalResource.getContents());
		// while (originalIterator.hasNext()) {
		// EObject original = originalIterator.next();
		//
		// String id = idMap.get(original);
		// // use the copier to find the copied element for the original
		// toSaveResource.setID(copier.get(original), id);
		// }
		//
		// // // clear all internal ids
		// // toSaveResource.getEObjectToIDMap().clear();
		// // if (toSaveResource.getIntrinsicIDToEObjectMap() != null) {
		// // toSaveResource.getIntrinsicIDToEObjectMap().clear();
		// // }

		return toSaveResource;
	}

	private void removeDanglingRefs(MPerspective perspective) {
		perspective.setParent(null);
		for(MUIElement child:perspective.getChildren()) {
			if(child instanceof MPartSashContainer) {
				iterateSash((MPartSashContainer)child);
			}
			if(child instanceof MPart) {
				clearPart((MPart)child);
			}
		}
	}
	
	private void iterateSash(MPartSashContainer sash) {
		for(MPartSashContainerElement element:((MPartSashContainer)sash).getChildren()) {
			if(element instanceof MPart) {
				clearPart((MPart)element);
			}
			if(element instanceof MPartSashContainer) {
				iterateSash((MPartSashContainer) element);
			}
		}
	}

	private void clearPart(MPart part) {
		if(part.getBindingContexts() != null) {
			part.getBindingContexts().clear();
		}
		if(part.getToolbar() != null) {
			part.setToolbar(null);
		}
	}
}
