/*******************************************************************************
 * 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
 *******************************************************************************/

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_).toURI().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;
	}
}
