/*******************************************************************************
 * Copyright (c) 2007 Oracle Corporation.
 * 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 - initial API and implementation
 *    
 ********************************************************************************/
package org.eclipse.jst.jsf.common.metadata.internal;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xmi.ClassNotFoundException;
import org.eclipse.emf.ecore.xmi.FeatureNotFoundException;
import org.eclipse.emf.ecore.xmi.IllegalValueException;
import org.eclipse.emf.ecore.xmi.PackageNotFoundException;
import org.eclipse.emf.ecore.xmi.UnresolvedReferenceException;
import org.eclipse.emf.ecore.xmi.XMIException;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.metadata.Model;
import org.eclipse.jst.jsf.common.metadata.internal.util.MetadataResourceImpl;

/**
 * Singleton that produces and loads standard metadata models.  
 * All models are loaded into the same ResourceSet.
 * <p>
 * All metadata extension models must be registered with org.eclipse.emf.ecore.generated_package extension-point.
 * No other mechanism is provided for model uri resolution.
 * <p>
 * Debug tracing for model loading is available: <code>org.eclipse.jst.jsf.common/debug/metadataload=true</code>
 * <p>
 * When the /debug/metadataload trace flag is set, and in case extension models are known not to be available, 
 * and metadata is referencing those models, error logging can be suppressed by launching with the following properties set:<br>
 * &nbsp;&nbsp;&nbsp;metadata.package.ignores<br>
 * &nbsp;&nbsp;&nbsp;metadata.classname.ignores
 *  <p>
 *  eg. Usage for when WPE is not present<p>
 *  <code>
 	-Dmetadata.package.ignores=http://org.eclipse.jsf.pagedesigner/dtinfo.ecore,<br>http://org.eclipse.jsf.pagedesigner/QuickEditTabSections.ecore<br>
 	-Dmetadata.classname.ignores=DTInfo,QuickEditTabSections<br>
 *  </code>
 * <p>
 * see {@link Model}
 */
public class StandardModelFactory {
	private static StandardModelFactory INSTANCE;
	static boolean DEBUG_MD_LOAD = false;
	static boolean DEBUG_MD_GET = false;
	private ExtendedMetaData extendedMetaData;
	private ResourceSet resourceSet;

	
	/**
	 * @return singleton instance of the metadata model factory
	 */
	public synchronized static StandardModelFactory getInstance(){
		if (INSTANCE == null){
			INSTANCE = new StandardModelFactory();
			INSTANCE.init();	
			
			if (JSFCommonPlugin.getPlugin().isDebugging()){
				DEBUG_MD_LOAD = Boolean.valueOf(Platform.getDebugOption(JSFCommonPlugin.PLUGIN_ID+"/debug/metadataload")).booleanValue();//$NON-NLS-1$
				DEBUG_MD_GET  = Boolean.valueOf(Platform.getDebugOption(JSFCommonPlugin.PLUGIN_ID+"/debug/metadataget")).booleanValue();//$NON-NLS-1$
			}
		}
		return INSTANCE;
	}
	
	private void init() {
		resourceSet = new ResourceSetImpl();
		
	    extendedMetaData = new BasicExtendedMetaData(resourceSet.getPackageRegistry());
		
		// Register the appropriate resource factory to handle all file extensions.
		//
		resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put
			(Resource.Factory.Registry.DEFAULT_EXTENSION, 
			 new XMLResourceFactoryImpl());
		
		//relying on the org.eclipse.emf.ecore.generated_package ext-pt to register traits
	}

	private StandardModelFactory() {		
		super();
	}
	
//	/**
//	 * Factory method that probably belongs somewhere else!
//	 * @param key
//	 * @param strategy
//	 * @return an empty MetaDataModel
//	 * @deprecated
//	 */
//	public MetaDataModel createModel(ModelKeyDescriptor key, IDomainLoadingStrategy strategy){
//		return new MetaDataModel(key, strategy);
//	}
	
	/**
	 * @param context
	 * @param strategy
	 * @return MetaDataModel
	 */
	public MetaDataModel createModel(final IMetaDataModelContext context, final IDomainLoadingStrategy strategy) {
		return new MetaDataModel(context, strategy);
	}
//
//	/**
//	 * Factory method that probably belongs somewhere else!
//	 * @param modelContext 
//	 * @return a ModelKeyDescriptor for the context
//	 * @deprecated
//	 */
//	public ModelKeyDescriptor createModelKeyDescriptor(final ITaglibDomainMetaDataModelContext modelContext) {
//		return new ModelKeyDescriptor(modelContext.getProject(), modelContext.getDomainID(), modelContext.getURI());
//	}
	
	/**
	 * @param inputStream
	 * @param provider
	 * @param uri 
	 * @return the root of the standard model from the resource as an EList
	 * @throws IOException
	 */
	public EList loadStandardFileResource(final InputStream inputStream,
            final IMetaDataSourceModelProvider provider,
            final org.eclipse.emf.common.util.URI uri) throws IOException
    {
        final XMLResource res = new MetadataResourceImpl(provider);
        
        debug(String.format(
                ">>> Loading standard meta-data file for uri %s", uri), DEBUG_MD_LOAD); //$NON-NLS-1$
        
        res.setURI(uri);
        resourceSet.getResources().add(res);
        setLoadOptions(res);
        res.load(inputStream, null);
        if (DEBUG_MD_LOAD)
        {
            reportErrors(res);
        }
        final EList root = res.getContents();
        return root;
    }

	private void reportErrors(Resource res) {
		EList<Resource.Diagnostic> errs = res.getErrors();
		if (! errs.isEmpty()){
			for (Iterator<Resource.Diagnostic> it= errs.iterator();it.hasNext();){
				StandardModelErrorMessageFactory.logErrorMessage(it.next());
			}
		}
	}
	
	/**
	 * Sets default load options for the resource
	 * @param resource 
	 */
	protected void setLoadOptions(XMLResource resource) {
		Map options = resource.getDefaultLoadOptions();
//		options.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, true);
		options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
		options.put(XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData);
		options.put(XMLResource.OPTION_RESOURCE_HANDLER, resource);
		options.put(XMLResource.OPTION_LAX_FEATURE_PROCESSING, Boolean.TRUE);
		options.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.FALSE);//turning this off so that res.getErrors() has values to check!  bizarre that I should need to do this.
//		options.put(XMLResource.OPTION_DOM_USE_NAMESPACES_IN_SCOPE, Boolean.TRUE);
		
//		if (DEBUG_MD_LOAD)
//		{
//		    System.out.println("Using load options: "+options);
//		}
	}


	static class StandardModelErrorMessageFactory {
		private static List<String> _missingPackageURIs;
		private static List<String> _missingClassnames;
		
		/**
		 * Simply logs all messages against JSFCommonPlugin, for now.
		 * @param diagnostic
		 */
		public static void logErrorMessage(Resource.Diagnostic diagnostic) {	
			//should be XMIException
			if (diagnostic instanceof XMIException) {
				XMIException ex = (XMIException)diagnostic;				
				String msg = createMessage(ex);
				if (msg != null)
					JSFCommonPlugin.log(IStatus.ERROR, msg);
			}
			else {
				JSFCommonPlugin.log(IStatus.ERROR, diagnostic.toString());//do better???
			}
		}

		private static String createMessage(XMIException ex) {
			
			StringBuffer buf = new StringBuffer("Metadata Load Error: ") //$NON-NLS-1$
				.append(ex.getClass().getSimpleName()).append(": "); //$NON-NLS-1$
			
			if (ex instanceof PackageNotFoundException) {				
				if (shouldIgnore(ex)) 
					return null;
				
				buf.append(((PackageNotFoundException)ex).uri());			
			} 
			else if (ex instanceof ClassNotFoundException) {
				if (shouldIgnore(ex)) 
					return null;
				
				buf.append(((ClassNotFoundException)ex).getName());
			}
			else if (ex instanceof FeatureNotFoundException)
				buf.append(((FeatureNotFoundException)ex).getName());
			else if (ex instanceof IllegalValueException)
				buf.append(((IllegalValueException)ex).getValue().toString());
			else if (ex instanceof UnresolvedReferenceException)
				buf.append(((UnresolvedReferenceException)ex).getReference());	
			else
				buf.append(ex.getMessage());
			
			buf.append(" in ").append(ex.getLocation()).append(": Line = ") //$NON-NLS-1$ //$NON-NLS-2$
				.append(ex.getLine()).append(": Column = ").append(ex.getColumn()); //$NON-NLS-1$
			return buf.toString();
		}

		private static boolean shouldIgnore(XMIException ex) {
			if (ex instanceof PackageNotFoundException) {
				String uri = ((PackageNotFoundException)ex).uri();
				return getMissingPackageURIs().contains(uri);
			}
			else if (ex instanceof ClassNotFoundException) {
				String className = ((ClassNotFoundException)ex).getName();
				return getMissingClassnames().contains(className);
			}
			return false;
		}

		private static List<String> getMissingPackageURIs() {
			if (_missingPackageURIs == null) {
				_missingPackageURIs = buildList("metadata.package.ignores"); //$NON-NLS-1$

			}
			return _missingPackageURIs;
		}
		
		private static List<String> getMissingClassnames() {
			if (_missingClassnames == null) {
				_missingClassnames = buildList("metadata.classname.ignores"); //$NON-NLS-1$
			}
			return _missingClassnames;
		}

		private static List<String> buildList(String propertyName) {
			List<String> ret = new ArrayList<String>();
			String ignoreSet = System.getProperty(propertyName);
			if (ignoreSet == null )//try env
				ignoreSet = System.getenv(propertyName);
			
			if (ignoreSet != null && !(ignoreSet.equals(""))){ //$NON-NLS-1$
				StringTokenizer st = new StringTokenizer(ignoreSet, ","); //$NON-NLS-1$
				while(st.hasMoreTokens()){
					String uri = st.nextToken();
					if (!(uri.equals(""))) //$NON-NLS-1$
							ret.add(uri);
				}
			}

			return ret;
		}
		 
	}
	
	/**
	 * Debug output.  The parenthesis shows thread id.
	 * @param msg
	 * @param debugFlag
	 */
	public static void debug(String msg, boolean debugFlag) {
		if (debugFlag)
			System.out.println(msg + "["+Thread.currentThread().getId()+"]"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	
}
