/*******************************************************************************
 * Copyright (c) 2005 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 Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060517   131582 mahutch@ca.ibm.com - Mark Hutchinson
 *******************************************************************************/

package org.eclipse.wst.ws.internal.registry;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.wst.ws.internal.model.v10.registry.Registry;
import org.eclipse.wst.ws.internal.model.v10.rtindex.Index;
import org.eclipse.wst.ws.internal.model.v10.rtindex.RTIndexFactory;
import org.eclipse.wst.ws.internal.model.v10.taxonomy.Taxonomy;
import org.eclipse.wst.ws.internal.plugin.WSPlugin;

/**
 * A typical implementation of <code>IRegistryManager</code>.
 * @author cbrealey
 * @see IRegistryManager
 */
public class RegistryManager implements IRegistryManager
{
	private static String REGISTRY = "Registry";
	private static String TAXONOMY = "Taxonomy";
	private static String XML = "xml";
	private Hashtable taxonomyFinders_;
	private Index index_;
	private GenericResourceFactory resourceFactory_ = new GenericResourceFactory();
	private URL registryURL_= null;
	private String registryPathname_ = null;

	/**
	 * Constructs a new RegistryManager for the index XML file
	 * at the given <code>url</code>.
	 * @param url The URL to the index XML file.
	 */
	RegistryManager ( URL url )
	{
		registryURL_ = url;
		taxonomyFinders_ = new Hashtable();
	}

	/**
	 * Constructs a new RegistryManager for the index XML file
	 * at the given <code>pathname</code>.
	 * @param pathname The pathname to the index XML file.
	 */
	RegistryManager ( String pathname )
	{
		registryPathname_ = pathname;
		taxonomyFinders_ = new Hashtable();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getURL()
	 */
	public URL getURL () throws MalformedURLException
	{
		if (registryURL_ == null)
		{
			registryURL_ = new File(registryPathname_).toURL();
		}
		return registryURL_;
	}

	/**
	 * Returns an absolute URL computed from the absolute URL of the
	 * index XML document managed by this <code>RegistryManager</code>
	 * and the given <code>id</code>. This method is used to determine
	 * a reasonable location URL for registry and taxonomy documents
	 * when references to them are first to be added to the index XML
	 * document. This method is idempotent insofar as it will always
	 * compute the same URL for a given <code>RegistryManager</code>
	 * and a given <code>id</code>.
	 * 
	 * @param id The id of the referenced registry or taxonomy document. 
	 * @return The absolute URL to the referenced document.
	 * @throws MalformedURLException If a viable absolute URL cannot
	 * be computed.
	 */
	private URL getURL ( String id ) throws MalformedURLException
	{
		String baseUrl = ""; 
		URL indexUrl = getURL();
		String indexString = indexUrl.toString();
		int index = indexString.lastIndexOf("/"); 
		baseUrl = indexString.substring(0,index + 1);
		String urlString = baseUrl + id + "." + XML;
		return new URL(urlString);
	}

	/**
	 * Caches and returns the index model. On first call,
	 * if an index document exists, the index is loaded
	 * from it, otherwise, a new index is returned.
	 * @return The index.
	 * @throws CoreException If the index cannot be loaded for any reason.
	 */
	private Index getIndex () throws CoreException
	{
		if (index_ == null)
		{
			try
			{
				URL indexURL = getURL();
				if (RegistryService.exists(indexURL))
				{
					Resource resource = resourceFactory_.createResource(URI.createURI("*.xml"));
					resource.load(RegistryService.getInputStreamFor(indexURL),null);
					org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot document = (org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot)resource.getContents().get(0);
					index_ = document.getIndex();
				}
				else
				{
					index_ = RTIndexFactory.eINSTANCE.createIndex();
				}
			}
			catch (IOException e)
			{
				//TODO: Need a message for this Status.
				throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",e));
			}
		}
		return index_;
	}

	/**
	 * Saves the index model to an XML document.	
	 * @throws CoreException If the save fails for any reason.
	 */
	private void saveIndex () throws CoreException
	{
		org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot document = RTIndexFactory.eINSTANCE.createDocumentRoot();
		document.setIndex(getIndex());
		Resource resource = resourceFactory_.createResource(URI.createURI("*.xml"));
		resource.getContents().add(document);
		try
		{
			resource.save(RegistryService.getOutputStreamFor(getURL()),null);
		}
		catch (IOException e)
		{
			//TODO: Need a message for this Status.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",e));
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#addTaxonomyFinder(java.lang.String, org.eclipse.wst.ws.internal.registry.ITaxonomyFinder)
	 */
	public void addTaxonomyFinder(String className, ITaxonomyFinder taxonomyFinder)
	{
		taxonomyFinders_.put(className,taxonomyFinder);
	}
	
	/**
	 * Adds the given <code>registry</code> as-is, whether full model
	 * or reference, to the index only if a registry with the same ID
	 * or reference is not already stored there.
	 * @param registry The registry to add.
	 */
	private void addRegistryToIndex(Registry registry) throws CoreException
	{
		String id = registry.getId();
		if (id == null) id = registry.getRef();
		if (id != null && getRegistry(id) == null)
		{
			getIndex().getRegistry().add(registry);
		}
	}
	
	/**
	 * Adds the given <code>taxonomy</code> as-is, whether full model
	 * or reference, to the index only if a taxonomy with the same ID
	 * or reference is not already stored there.
	 * @param taxonomy The taxonomy to add.
	 */
	private void addTaxonomyToIndex(Taxonomy taxonomy) throws CoreException
	{
		String id = taxonomy.getId();
		if (id == null) id = taxonomy.getRef();
		if (id != null && getTaxonomy(id) == null)
		{
		 	getIndex().getTaxonomy().add(taxonomy);	
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#saveRegistry(org.eclipse.wst.ws.internal.model.v10.registry.Registry)
	 */
	public Registry saveRegistry ( Registry registry ) throws CoreException
	{
		RegistryService registryService = RegistryService.instance();
		Registry registryRef = null;
		try
		{
			URL url = getURL(REGISTRY + registry.getId());
			registryService.saveRegistry(url,registry);
			registryRef = registryService.newRegistryReference(registry);
			registryRef.setLocation(url.toString());
			addRegistryToIndex(registryRef);
			saveIndex();
			/*
			 * TODO: The following pile of code is commented out
			 * since there isn't a reliable way under the current
			 * design to save taxonomy models held in a registry model
			 * 
			ITaxonomyFinder finder = (ITaxonomyFinder)taxonomyFinders_.get(registry.getClass().getName());
			if (finder != null)
			{
				Taxonomy[] taxonomies = finder.taxonomies(registry);
				for (int i=0; i<taxonomies.length; i++)
				{
					String id = taxonomies[i].getId();
					String ref = taxonomies[i].getRef();
					if (id != null)
					{
						URL taxonomyURL = getURL(TAXONOMY + id);
						registryService.saveTaxonomy(taxonomyURL,taxonomies[i]);
						Taxonomy taxonomyRef = registryService.newTaxonomyReference(taxonomies[i]);
						taxonomyRef.setLocation(taxonomyURL.toString());
						addTaxonomyToIndex(taxonomyRef);
					}
					else if (ref != null)
					{
						if (taxonomies[i].getLocation() == null)
						{
							String location = null;
							Taxonomy taxonomy = getTaxonomy(ref);
							if (taxonomy != null) location = taxonomy.getLocation();
							if (location == null) location = getURL(TAXONOMY + ref).toString();
							taxonomies[i].setLocation(location);
							if (taxonomy == null)
							{
								addTaxonomyToIndex(registryService.newTaxonomyReference(taxonomies[i]));
							}
						}
					}
				}
			}
		    */
		}
		catch ( MalformedURLException me )
		{
			//TODO: Message text required.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
		}
		return registryService.newRegistryReference(registryRef);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadRegistry(java.lang.String)
	 */
	public Registry loadRegistry ( String uri ) throws CoreException
	{
		RegistryService registryService = RegistryService.instance();
		try
		{
			Registry registry = getRegistry(uri);
			if (registry == null) return null;

			// If the Registry has an ID, it's a full model
			// inlined within the Index and is returned as-is.
			if (registry.getId() != null) return registry;

			// Otherwise it's a reference to a full model
			// which we load from the reference's location.
			String urlString = registry.getLocation();
			if (urlString == null) return null;
			URL url = new URL(urlString);
			return registryService.loadRegistry(url);
		}
		catch ( MalformedURLException me )
		{
			//TODO: Message text required.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadRegistries(java.lang.String[])
	 */
	public Registry[] loadRegistries ( String[] uris ) throws CoreException
	{
		List list = new ArrayList(uris.length);
		for (int i=0; i<uris.length; i++)
		{
			Registry registry = loadRegistry(uris[i]);
			if (registry != null)
			{
				list.add(registry);
			}
		}
		return (Registry[])list.toArray(new Registry[0]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getRegistryURIs()
	 */
	public String[] getRegistryURIs () throws CoreException
	{
		EList list = getIndex().getRegistry();
		List registryURIs = new ArrayList(list.size());
		Iterator iterator = list.iterator();
		while(iterator.hasNext())
		{
			// Each Registry found in the index may be
			// either a full model or a reference to one.
			Registry registry = (Registry)iterator.next();
			if (registry.getId() != null)
			{
				registryURIs.add(registry.getId());
			}
			else if (registry.getRef() != null)
			{
				registryURIs.add(registry.getRef());
			}
		}	
		return (String[])registryURIs.toArray(new String[0]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#removeRegistry(java.lang.String, boolean)
	 */
	public void removeRegistry ( String uri, boolean deleteDocument ) throws CoreException
	{
		EList list = getIndex().getRegistry();
		Registry registry = getRegistry(uri);
		if (registry != null)
		{
			list.remove(registry);
			saveIndex();
			// The identified Registry may be either a full model
			// (ie. inlined in the Index) or a reference to one.
			// Only in the latter case is there a file to delete.
			if (deleteDocument && registry.getLocation() != null)
			{
				//TODO: Implement me.
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#saveTaxonomy(org.eclipse.wst.ws.internal.model.v10.taxonomy.Taxonomy)
	 */
	public Taxonomy saveTaxonomy ( Taxonomy taxonomy ) throws CoreException
	{
		RegistryService registryService = RegistryService.instance();
		Taxonomy taxonomyRef = null;
		try
		{
			URL	url = getURL(TAXONOMY + taxonomy.getId());
		    registryService.saveTaxonomy(url,taxonomy);
			taxonomyRef = registryService.newTaxonomyReference(taxonomy);
			taxonomyRef.setLocation(url.toString());
			addTaxonomyToIndex(taxonomyRef);
			saveIndex();
		}
		catch ( MalformedURLException me )
		{
			//TODO: Message text required.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
		}
		return registryService.newTaxonomyReference(taxonomyRef);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadTaxonomy(java.lang.String)
	 */
	public Taxonomy loadTaxonomy ( String uri ) throws CoreException
	{
		RegistryService registryService = RegistryService.instance();
		try
		{
			Taxonomy taxonomy = getTaxonomy(uri);
			if (taxonomy == null) return null;

			// If the Taxonomy has an ID, it's a full model
			// inlined within the Index and is returned as-is.
			if (taxonomy.getId() != null) return taxonomy;

			// Otherwise it's a reference to a full model
			// which we load from the reference's location.
			String urlString = taxonomy.getLocation();
			if (urlString == null) return null;
			URL url = new URL(urlString);
			return registryService.loadTaxonomy(url);
		}
		catch ( MalformedURLException me )
		{
			//TODO: Message text required.
			throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadTaxonomies(java.lang.String[])
	 */
	public Taxonomy[] loadTaxonomies ( String[] uris ) throws CoreException
	{
		List list = new ArrayList(uris.length);
		for (int i=0; i<uris.length; i++)
		{
			Taxonomy taxonomy = loadTaxonomy(uris[i]);
			if (taxonomy != null)
			{
				list.add(taxonomy);
			}
		}
		return (Taxonomy[])list.toArray(new Taxonomy[0]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getTaxonomyURIs()
	 */
	public String[] getTaxonomyURIs () throws CoreException
	{
		EList list = getIndex().getTaxonomy();
		List taxonomyURIs = new ArrayList(list.size());
		Iterator iterator = list.iterator();
		while(iterator.hasNext())
		{
			// Each Taxonomy found in the index may be
			// either a full model or a reference to one.
			Taxonomy taxonomy = (Taxonomy)iterator.next();
			if (taxonomy.getId() != null)
			{
				taxonomyURIs.add(taxonomy.getId());
			}
			else if (taxonomy.getRef() != null)
			{
				taxonomyURIs.add(taxonomy.getRef());
			}
		}	
		return (String[])taxonomyURIs.toArray(new String[0]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.internal.registry.IRegistryManager#removeTaxonomy(java.lang.String, boolean)
	 */
	public void removeTaxonomy ( String uri, boolean deleteDocument ) throws CoreException
	{
		EList list = getIndex().getTaxonomy();
		Taxonomy taxonomy = getTaxonomy(uri);
		if (taxonomy != null)
		{
			list.remove(taxonomy);
			saveIndex();
			// The identified Taxonomy may be either a full model
			// (ie. inlined in the Index) or a reference to one.
			// Only in the latter case is there a file to delete.
			if (deleteDocument && taxonomy.getLocation() != null)
			{
				//TODO: Implement me.
			}
		}
	}

	/**
	 * Returns the Registry from the index whose ID or Reference
	 * matches the given URI. As such, this method may return a
	 * full model or a reference to a full model.
	 * @param uri The URI identifier of the Registry
	 * @return The <code>Registry</code> object whose ID or reference
	 * matches the given <code>uri</code>, or null if none match.
	 */
    private Registry getRegistry ( String uri ) throws CoreException
    {
		EList list = getIndex().getRegistry();	
		Iterator it = list.iterator();
		while (it.hasNext()){
			Registry registry = (Registry)it.next();
			if (uri.equals(registry.getId()) || uri.equals(registry.getRef())){
				return registry;  
			}
		}	
        return null;
    }
	
	/**
	 * Returns the Taxonomy from the index whose ID or Reference
	 * matches the given URI. As such, this method may return a
	 * full model or a reference to a full model.
	 * @param uri The URI identifier of the Taxonomy
	 * @return The <code>Taxonomy</code> object whose ID or reference
	 * matches the given <code>uri</code>, or null if none match.
	 */
    private Taxonomy getTaxonomy ( String uri ) throws CoreException
    {
		EList list = getIndex().getTaxonomy();	
		Iterator it = list.iterator();
		while (it.hasNext()){
			Taxonomy taxonomy = (Taxonomy)it.next();
			if (uri.equals(taxonomy.getId()) || uri.equals(taxonomy.getRef())){
				return taxonomy;
			}
		}	
        return null;
	}
}
