/*******************************************************************************
 * Copyright (c) 2006 Oracle 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:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpmn2.modeler.core.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceFactoryRegistryImpl;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;


/**
 * @author Michal Chmielewski (michal.chmielewski@oracle.com)
 * @date Apr 17, 2007
 *
 */


@SuppressWarnings("nls")

public class Bpmn2ModelerResourceSetImpl extends ResourceSetImpl implements IResourceChangeListener {
	// this ID identifies the BPMN file content type
	public static final String BPMN2_CONTENT_TYPE = "org.eclipse.bpmn2.content-type.xml"; //$NON-NLS-1$
	 
	private String connectionTimeout;
	private String readTimeout;

	public Bpmn2ModelerResourceSetImpl() {
		super();
	}

	/**
	 * Used to force loading using the right resource loaders.
	 */
	static public final String SLIGHTLY_HACKED_KEY = "slightly.hacked.resource.set";
	
	/* (non-Javadoc)
	 * 
	 * Intercept getEObject() calls and validate the URI.
	 * This allows us to use arbitrary proxy URIs for things like ItemDefinition.structureRef
	 * 
	 * Also handle the setting of connection timeout here for URIs that do not point to physical
	 * resources, or resources that are currently unavailable due to (e.g. possibly) server outages.
	 * 
	 * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getEObject(org.eclipse.emf.common.util.URI, boolean)
	 */
	@Override
	public EObject getEObject(URI uri, boolean loadOnDemand) {
		EObject o = null;
		if (uri!=null) {
			uri.trimFragment();
			if (uri.fragment()!=null) {
				setDefaultTimeoutProperties();
				o = super.getEObject(uri, loadOnDemand);
				restoreTimeoutProperties();
			}
		}
		return o;
	}

	private void saveTimeoutProperties() {
		if (connectionTimeout==null) {
			connectionTimeout = System.getProperty("sun.net.client.defaultConnectTimeout");
			if (connectionTimeout==null)
				connectionTimeout = "";
		}
		if (readTimeout==null) {
			readTimeout = System.getProperty("sun.net.client.defaultReadTimeout");
			if (readTimeout==null)
				readTimeout = "";
		}
	}
	
	private void restoreTimeoutProperties() {
		if(connectionTimeout!=null) {
			System.setProperty("sun.net.client.defaultConnectTimeout", connectionTimeout);
			connectionTimeout = null;
		}
		if (readTimeout!=null) {
			System.setProperty("sun.net.client.defaultReadTimeout", readTimeout);
			readTimeout = null;
		}
	}
	
	private void setDefaultTimeoutProperties() {
		saveTimeoutProperties();
		String timeout = Bpmn2Preferences.getInstance().getConnectionTimeout();
		System.setProperty("sun.net.client.defaultConnectTimeout", timeout);
		System.setProperty("sun.net.client.defaultReadTimeout", timeout);
	}

	/**
	 * Load the resource from the resource set, assuming that it is the kind
	 * indicated by the last argument. The "kind" parameter is the extension 
	 * without the . of the resource.
	 * 
	 * This forces the right resource to be loaded even if the URI of the resource
	 * is "wrong".
	 * 
	 * @param uri the URI of the resource.
	 * @param loadOnDemand load on demand
	 * @param kind the resource kind. It has to be of the form "*.wsdl", or "*.xsd", or "*.bpmn"
	 * @return the loaded resource. 
	 */
	
	@SuppressWarnings("nls")
	public Resource getResource(URI uri, boolean loadOnDemand, String kind)  {

		// Bugzilla 324164
		// don't bother if URI is null or empty
		if (uri==null || uri.isEmpty())
			return null;
		Map<URI, Resource> map = getURIResourceMap();
		
		if (map != null) {
			Resource resource = map.get(uri);
			if (resource != null) {
				if (loadOnDemand && !resource.isLoaded()) {
					// Bugzilla 324164
					// if load fails, mark resource as unloaded
					try {
						demandLoadHelper(resource);
					} catch (Exception ex) {
						resource.unload();
					}
				}
				
				return resource;
			}
		}

		URIConverter theURIConverter = getURIConverter();
		URI normalizedURI = theURIConverter.normalize(uri);
		
		for (Resource resource : getResources()) {
			if (theURIConverter.normalize(resource.getURI()).equals(
					normalizedURI)) {
				if (loadOnDemand && !resource.isLoaded()) {
					// Bugzilla 324164
					// if load fails, mark resource as unloaded
					try {
						demandLoadHelper(resource);
					} catch (Exception ex) {
						resource.unload();
						break;
					}
				}

				if (map != null) {
					map.put(uri, resource);
				}
				return resource;
			}			
		}
		
		if (loadOnDemand) {
			Resource resource = demandCreateResource(uri,kind);
			if (resource == null) {
				throw new RuntimeException("Cannot create a resource for '"
						+ uri + "'; a registered resource factory is needed");
			}

			demandLoadHelper(resource);

			if (map != null) {
				map.put(uri, resource);
			}
			return resource;
		}

		return null;
	}
	
	
	protected Resource demandCreateResource ( URI uri, String kind ) {
		return createResource ( uri, kind );
	}
	
	/*
	 * Fix for Bug 278205 - Problem with importing remote WSIL/WSDL still exists.
	 * Telesh Alexandr added this method to solve this which is to load remote WSIL/WSDL 
     * by the correct resource loader based on known before loading resouce 
     * extension which is posed as resource content type.
	 */
	public Resource.Factory.Registry getResourceFactoryRegistry() {
		if (resourceFactoryRegistry == null) {

			resourceFactoryRegistry = new ResourceFactoryRegistryImpl() {
				@Override
				protected Resource.Factory delegatedGetFactory(URI uri, String contentTypeIdentifier) {
					// patch for "wsil" and "wsdl" resources without extensions
					final Map<String, Object> extensionToFactoryMap =
						Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap();
					
					final Object wsilFactory = extensionToFactoryMap.get("wsil");
					final Object wsdlFactory = extensionToFactoryMap.get("wsdl");
					
					final Map<String, Object> contentTypeToFactoryMap = 
						Resource.Factory.Registry.INSTANCE.getContentTypeToFactoryMap();
					
					if (null != wsilFactory) {
						contentTypeToFactoryMap.put("wsil", wsilFactory);
					}
					if (null != wsdlFactory) {
						contentTypeToFactoryMap.put("wsdl", wsdlFactory);
					}

					return convert(getFactory(uri,
							Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap(),
							extensionToFactoryMap, contentTypeToFactoryMap,
							contentTypeIdentifier, false));
				}

				@Override
				protected URIConverter getURIConverter() {
					// return ResourceSetImpl.this.getURIConverter();
					return Bpmn2ModelerResourceSetImpl.this.getURIConverter();
				}

				@Override
				protected Map<?, ?> getContentDescriptionOptions() {
					return getLoadOptions();
				}
			};
		}
		return resourceFactoryRegistry;
	}
	
	/**
	 * Create the resource based on the kind.
	 * @param uri
	 * @param kind
	 * @return the created resource
	 */
	
	// TODO: ganymede [ this method apparently is already in the parent resource set ]
	// we can strike it from this resourceset.
	
//	@SuppressWarnings("nls")
//	public Resource createResource ( URI uri, String kind) {
//		
//		if (kind == null) {
//			return super.createResource(uri);
//		}
//		
//		Resource resource = createResource(URI.createURI("*." + kind)); 
//		resource.setURI(uri);		
//		return resource;
//	}


	
	
	
	
	/**
	 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
	 */
	public void resourceChanged (IResourceChangeEvent event) {
		
		// System.out.println("IResourceChangeEvent: " + event + "; " + event.getType()  );				
		IResourceDelta[] deltas = event.getDelta().getAffectedChildren( IResourceDelta.CHANGED | IResourceDelta.REMOVED, IResource.FILE );	
		processDeltas ( deltas );
	}
	
	void processDeltas ( IResourceDelta [] deltas ) {
		
		for(IResourceDelta delta : deltas) {			
			processDeltas( delta.getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.REMOVED, IResource.FILE) );
			
			IResource resource = delta.getResource();
			if (resource.getType () != IResource.FILE) {
				continue;
			}
			
			if (delta.getKind() == IResourceDelta.REMOVED){
				resourceChanged((IFile)resource);
				continue;
			}
			
//			 * @see IResourceDelta#CONTENT
//			 * @see IResourceDelta#DESCRIPTION
//			 * @see IResourceDelta#ENCODING
//			 * @see IResourceDelta#OPEN
//			 * @see IResourceDelta#MOVED_TO
//			 * @see IResourceDelta#MOVED_FROM
//			 * @see IResourceDelta#TYPE
//			 * @see IResourceDelta#SYNC
//			 * @see IResourceDelta#MARKERS
//			 * @see IResourceDelta#REPLACED
			 
			if ((delta.getFlags() & IResourceDelta.CONTENT) == 0){
				continue;
			}
			
			// TODO: Temporary hack
			// Actually we should remove all resources from the resourceSet,
			// but for some reasons bpmn files can't be removed now
			// Bugzilla 320545:
			if (isBPMN2File(resource)){
				continue;
			}
			
			resourceChanged((IFile) resource);
		}		
	}
	
	public void setLoadOptions (Map<Object, Object> options) {
		loadOptions = options;
	}
	
	/**
	 * Resource has changed, remove it from the cache or list of loaded resources.
	 * 
	 * @param file
	 */
	public void resourceChanged (IFile file) {
		// System.out.println("ResourceChanged: " + file  );
		URI uri = URI.createPlatformResourceURI( file.getFullPath().toString() ) ;		
		// System.out.println("    ResourceURI: " + uri );		
		URIConverter theURIConverter = getURIConverter();
		URI normalizedURI = theURIConverter.normalize(uri);
				
		if (uriResourceMap != null) {
			uriResourceMap.remove(uri);
			uriResourceMap.remove(normalizedURI);
			// System.out.println("Removed from Map: " + map );
		}
				
		List<Resource> resourceList = getResources();
		if (resources.size() < 1) {
			return ;
		}
		
		for(Resource r : new ArrayList<Resource>(resourceList) )  {
			if (uri.equals(r.getURI()) || normalizedURI.equals(r.getURI() )) {
				resources.remove(r);
				// System.out.println("Removed from List: " + r );				
			}
		}
	}

	// Bugzilla 320545:
	public static boolean isBPMN2File(IResource res)
	{
		try
		{
			if (res.getType() == IResource.FILE) {
				IContentDescription desc = ((IFile) res).getContentDescription();
				if (desc != null) {
					IContentType type = desc.getContentType();
					if (type.getId().equals(BPMN2_CONTENT_TYPE))
						return true;
				}
			}
		}
		catch(Exception ex)
		{
		}
		return false;	
	}
}
