/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  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:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
package org.eclipse.osbp.bpmn2.ecore;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.util.Bpmn2ResourceImpl;
import org.eclipse.bpmn2.util.QNameURIHandler;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.ecore.xmi.XMLLoad;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl;
import org.eclipse.osbp.bpmn2.common.WebServiceUtilities;
import org.xml.sax.helpers.DefaultHandler;

public class BPMnResourceImpl extends Bpmn2ResourceImpl {

	private QNameURIHandler uriHandler;

	public BPMnResourceImpl(URI uri) {
		super(uri);

		// we create a new uriHandler to allows "java.lang.Integer"-URIs
		this.uriHandler = new CustomQNameURIHandler(
				(BpmnXmlHelper) createXMLHelper());
		this.getDefaultLoadOptions().put(XMLResource.OPTION_URI_HANDLER,
				uriHandler);
		this.getDefaultSaveOptions().put(XMLResource.OPTION_URI_HANDLER,
				uriHandler);
	}

	private final static String URI_HANDLER = XMLResource.OPTION_URI_HANDLER;

	protected static class BPMnXmlHandler extends BpmnXmlHandler {

		public BPMnXmlHandler(XMLResource xmiResource, XMLHelper helper,
				Map<?, ?> options) {
			super(xmiResource, helper, options);
		}

		/**
		 * Overridden to be able to convert QName references in attributes to
		 * URIs during load.
		 * 
		 * @param ids
		 *            In our case the parameter will contain exactly one QName
		 *            that we resolve to URI.
		 */
		@Override
		protected void setValueFromId(EObject object, EReference eReference,
				String ids) {
			if (eReference == Bpmn2Package.Literals.ITEM_DEFINITION__STRUCTURE_REF) {
				super.setValueFromId(
						object,
						eReference,
						eReference.isResolveProxies() ? ((CustomQNameURIHandler) uriHandler)
								.convertQNameWithDotsToUri(ids) : ids);
			} else {
				super.setValueFromId(
						object,
						eReference,
						eReference.isResolveProxies() ? ((QNameURIHandler) uriHandler)
								.convertQNameToUri(ids) : ids);
			}
		}
	}

	@Override
	public EObject getEObject(String uriFragment) {
		EObject retcode = super.getEObject(uriFragment);
		if	((retcode == null) && uriFragment.equals(WebServiceUtilities.class.getCanonicalName())) {
			EClass a = EcoreFactory.eINSTANCE.createEClass();
			a.setName(uriFragment);
			retcode = a;
		}
		return retcode;
	}
	
	public void load(Map<?, ?> options) throws IOException {
		Map<?, ?> customOptions = options != null ? new HashMap<Object, Object>(options) : new HashMap<Object, Object>();
		customOptions.remove(URI_HANDLER);
		super.load(customOptions);
	}

	/**
	 * We must override this method for having an own XMLHandler
	 */
	@Override
	protected XMLLoad createXMLLoad() {
		return new XMLLoadImpl(createXMLHelper()) {
			@Override
			protected DefaultHandler makeDefaultHandler() {
				return new BPMnXmlHandler(resource, helper, options);
			}
		};
	}

	private static class CustomQNameURIHandler extends QNameURIHandler {

		private BpmnXmlHelper xmlHelper;

		public CustomQNameURIHandler(BpmnXmlHelper xmlHelper) {
			super(xmlHelper);

			this.xmlHelper = xmlHelper;
		}

		public String convertQNameWithDotsToUri(String qName) {

			if (qName.contains("#") || qName.contains("/")) {
				// We already have an URI and not QName, e.g. URL
				return qName;
			}

			// Split into prefix and local part (fragment)
			String[] parts = qName.split(":");
			String prefix, fragment;
			if (parts.length == 1) {
				prefix = null;
				fragment = qName;
			} else if (parts.length == 2) {
				prefix = parts[0];
				fragment = parts[1];
			} else
				throw new IllegalArgumentException("Illegal QName: " + qName);

			// Attention:
			// In difference to QNameURIHandler, we allow Dot-URIs in this
			// method!
			//
			//
			// if (fragment.contains(".")) {
			// // HACK: officially IDs can contain ".", but unfortunately
			// XmlHandler calls resolve also for xsi:schemaLocation stuff and
			// similar, that are
			// // NO URIs. We must not process them.
			// return qName;
			// }

			if (!xmlHelper.isTargetNamespace(prefix))
				return xmlHelper.getPathForPrefix(prefix)
						.appendFragment(fragment).toString();
			else
				return baseURI.appendFragment(fragment).toString();

		}

	}

}
