/*******************************************************************************
 * 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.Iterator;
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;


/**
 * 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 synchronized 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 = 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 = mdFilesMap.get(uri);
		if (providers == null) {
			providers = new ArrayList<IMetaDataSourceModelProvider>();
			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){
						final Model aModel = (Model)getSourceModel();
						final Trait t = getImageBasePath(aModel);
						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;
				}
				
				private Trait getImageBasePath(final Model aModel) {
					for (final Iterator it= aModel.getTraits().iterator(); it.hasNext();) {
						Trait t = (Trait)it.next();
						if (t.getId().equals("images-base-path")){ //$NON-NLS-1$
							return t;
						}
					}
					return null;
				}
				
			};
		
		} 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;
	}

}
}
