/*******************************************************************************
 * Copyright (c) 2002, 2006, 2007 IBM 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:
 *   IBM - Initial API and implementation
 *   Jens Lukowski/Innoopract - initial renaming/restructuring
 * 	 Gerry Kessler/Oracle - code borrowed and repurposed for JSF subproject
 *
 *******************************************************************************/
package org.eclipse.jst.jsf.common.metadata.internal;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.metadata.Model;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.query.TaglibDomainMetaDataQueryHelper;


/**
 * Registry of standard metadata files
 */
public final class StandardMetaDataFileRegistry {
	private Map/*<String, List<IMetaDataSourceModelProvider>>*/ mdFilesMap 	= new HashMap/*<String, List<IMetaDataSourceModelProvider>>*/(1);
	private List/*<IMetaDataSourceModelProvider>*/ EMPTY_LIST 	= new ArrayList/*<IMetaDataSourceModelProvider>*/(0);

	private static StandardMetaDataFileRegistry reg;
	
	/**
	 * @return the singleton instance of the registry
	 */
	public static StandardMetaDataFileRegistry getInstance() {
		if (reg == null){
			reg = new StandardMetaDataFileRegistry();
		}
		return reg;
	}
	
	private StandardMetaDataFileRegistry() {
		new StandardMetaDataFileRegistryReader(this).readRegistry();
	}

	/**
	 * @param uri as String
	 * @return list of standard metadata sources as <code>IMetaDataSourceModelProvider</code>s.  
	 * Returns empty list of no standard metadata files are registered for the given uri.
	 */
	public synchronized List/*<IMetaDataSourceModelProvider>*/ getStandardMetaDataModelProviders(String uri) {
		List/*<IMetaDataSourceModelProvider>*/ theList = (List)mdFilesMap.get(uri);
		return theList != null ? theList : EMPTY_LIST ;
	}
		
	/**
	 * For use by registry reader only
	 * @param uri
	 * @param fileInfo 
	 */
	public synchronized void addStandardMetaDataFileInfo(String uri, IStandardMetaDataSourceInfo fileInfo) {
		List/*<IMetaDataSourceModelProvider>*/ providers = (List) mdFilesMap.get(uri);
		if (providers == null) {
			providers = new ArrayList/*<IStandardMetaDataSourceInfo>*/();
			mdFilesMap.put(uri, providers);
		}
		providers.add(new StandardMetaDataFilesProvider(fileInfo));
	}	
	
/**
 * Internal implementation of IMetaDataSourceModelProvider for "standard" metadata sources
 *
 */
static class StandardMetaDataFilesProvider implements IMetaDataSourceModelProvider {
	
	private org.eclipse.jst.jsf.common.metadata.internal.IStandardMetaDataSourceInfo info;
	private Object model;
	private IMetaDataLocator locator;
	private StandardMetaDataSourceFileLocator fileLocator = null;
	
	/**
	 * Constructor
	 * @param info
	 */
	StandardMetaDataFilesProvider(IStandardMetaDataSourceInfo info){
		this.info = info;
	}
	
	private StandardMetaDataSourceFileLocator getFileLocator(){
		if (fileLocator == null){		
			if (info.getLocatorClassname() == null){
				fileLocator = new PluginRelativeStandardMetaDataSourceFileLocator();
			}	
			else {		
				Class klass = JSFCommonPlugin.loadClass(info.getLocatorClassname(), info.getBundleId());
				try {
					fileLocator = (StandardMetaDataSourceFileLocator)klass.newInstance();
				} catch (InstantiationException e) {
					JSFCommonPlugin.log(IStatus.ERROR, "InstantiationException: StandardMetaDataFilesProvider.getFileLocator()", e); //$NON-NLS-1$
				} catch (IllegalAccessException e) {
					JSFCommonPlugin.log(IStatus.ERROR, "IllegalAccessException: StandardMetaDataFilesProvider.getFileLocator()", e);				 //$NON-NLS-1$
				}			
			}
			if (fileLocator != null)
				fileLocator.setFileInfo(info);
		}
		return fileLocator;
	}
	
	private InputStream getInputStream() throws IOException {				
		if (getFileLocator() != null){
			return	getFileLocator().getInputStream();			
		}
		return null;
		
	}
	
	private URI getMDFileURI()
        {
            try
            {
                StandardMetaDataSourceFileLocator fileLocator2 = getFileLocator();
                if (fileLocator2 != null)
                {
                    final URL url = fileLocator2.getURL();
                    if (url == null)
                    {
                        JSFCommonPlugin.log(new RuntimeException(),
                                "Couldn't locate meta-data file for " //$NON-NLS-1$
                                        + fileLocator2.getFileInfo()
                                                .getLocation());
                        return null;
                    }

                    java.net.URI uri = url.toURI();
                    return URI.createURI(uri.toString());
                }
            }
            catch (URISyntaxException e)
            {
                JSFCommonPlugin.log(IStatus.ERROR, "Metadata File Load Error: " //$NON-NLS-1$
                        + getFileLocator().getFileInfo().toString()
                        + ": URISyntaxException: " + e.getMessage()); //$NON-NLS-1$
            }
            return null;
        }

	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataSourceModelProvider#getSourceModel()
	 */
	public Object getSourceModel() {
		if (model != null)
			return model;
		
		InputStream inputStream = null;
		try {
			URI uri = getMDFileURI();
			inputStream = getInputStream();
			if (inputStream != null && uri != null){
				EList contents = StandardModelFactory.getInstance().loadStandardFileResource(inputStream, this, uri);
				//check to see if this is a Model
				if (contents != null && !contents.isEmpty() &&
						contents.get(0) instanceof Model){				
					model = contents.get(0);
					((Model)model).setSourceModelProvider(this);
				}
			}
		} catch (FileNotFoundException e){
			JSFCommonPlugin.log(IStatus.ERROR, e.getLocalizedMessage());
		} catch (IOException e) {
			JSFCommonPlugin.log(IStatus.ERROR,"IOException(1): StandardMetaDataFilesProvider.getSourceModel():"+getModelName(), e); //$NON-NLS-1$			
		} finally {
			if (inputStream != null){
				try {
					inputStream.close();
				} catch (IOException e) {
					JSFCommonPlugin.log( IStatus.ERROR,"IOException (2): StandardMetaDataFilesProvider.getSourceModel():"+getModelName(), e); //$NON-NLS-1$
				}
			}
		}
		return model;
	}

	private String getModelName() {
		return info.toString();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataSourceModelProvider#getLocator()
	 */
	public IMetaDataLocator getLocator() {
		return locator;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataSourceModelProvider#setLocator(org.eclipse.jst.jsf.common.metadata.internal.IMetaDataLocator)
	 */
	public void setLocator(IMetaDataLocator locator) {
		this.locator = locator;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsf.common.metadata.internal.IMetaDataSourceModelProvider#getResourceBundle()
	 */
	private ResourceBundle internalGetResourceBundle() {
		if (getFileLocator() != null){
			try {
				return fileLocator.getResourceBundle();
			} catch (MissingResourceException e) {
				JSFCommonPlugin.log(IStatus.ERROR, "InternalGetResourceBundle1", e); //$NON-NLS-1$
			} catch (IOException e) {
				JSFCommonPlugin.log(IStatus.ERROR, "InternalGetResourceBundle2", e);			 //$NON-NLS-1$
			}
		}
		return null;
	}

	public Object getAdapter(Class klass) {
		final StandardMetaDataFilesProvider mdp = this;
		if (klass == IImageDescriptorProvider.class){			
			return new IImageDescriptorProvider(){
				String imageBase;
				public ImageDescriptor getImageDescriptor(String imagePath) {
					imagePath = appendImageBase(imagePath);
					String bundleID = mdp.getFileLocator().getFileInfo().getBundleId();
					URL url = FileLocator.find(Platform.getBundle(bundleID), new Path(imagePath), null);
					return ImageDescriptor.createFromURL(url);
				}
				private String appendImageBase(String imagePath) {
					return getImageBase() + imagePath;
				}
				
				private String getImageBase(){
					if (imageBase == null){
						Model aModel = (Model)getSourceModel();
						Trait t = TaglibDomainMetaDataQueryHelper.getTrait(aModel, "images-base-path"); //$NON-NLS-1$
						if (t == null){
							imageBase = "";		 //$NON-NLS-1$
						} else {
							imageBase = TraitValueHelper.getValueAsString(t);
							if (imageBase != null && imageBase.length() > 0){
								imageBase = imageBase +"/"; //$NON-NLS-1$
							}
						}
					}
					return imageBase;
				}
				
			};
		
		} else if (klass == IResourceBundleProvider.class) {
			return new IResourceBundleProvider(){

				public ResourceBundle getResourceBundle() {
					return mdp.internalGetResourceBundle();
				}
				
			};
			
		} else if (klass == IClassLoaderProvider.class){
			return new IClassLoaderProvider(){

				public Class loadClass(String className) {
					String bundleID = mdp.getFileLocator().getFileInfo().getBundleId();
					try {
						return Platform.getBundle(bundleID).loadClass(className);
					} catch (ClassNotFoundException e) {
						return null;
					}
				}
				
			};
		} else if (klass == IResourceURLProvider.class) {
			return new IResourceURLProvider() {

				public URL getResourceURL(String resourcePath) {
					URL resourceURL = null;
					String bundleID = mdp.getFileLocator().getFileInfo().getBundleId();
					try {
						resourceURL = FileLocator.resolve(Platform.getBundle(bundleID).getResource(resourcePath));
					} catch (IOException ioe) {
						//do nothing, will return null resourceURL
					}
					return resourceURL;
				}

			};
		}
		return null;
	}

}
}
