/*******************************************************************************
 * Copyright (c) 2002 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.core.internal.catalog;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
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 org.eclipse.core.runtime.Platform;
import org.eclipse.wst.xml.core.internal.Logger;
import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalog;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogElement;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogEntry;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogEvent;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogListener;
import org.eclipse.wst.xml.core.internal.catalog.provisional.INextCatalog;
public class Catalog implements ICatalog
{

	class CatalogLS
	{
		public void load()
		{
		}

		public synchronized void save()
		{
			try
			{
				new CatalogWriter().write(Catalog.this, location);
			} catch (Exception e)
			{
				Logger.logException(e);
			}
		}
	}

	class DefaultCatalogLS extends CatalogLS
	{
		public void load()
		{
			NextCatalog userCatalogReference = new NextCatalog();
			userCatalogReference.setId(XMLCorePlugin.USER_CATALOG_ID);
			userCatalogReference.setCatalogLocation(USER_CATALOG_FILE);
			addCatalogElement(userCatalogReference);

			NextCatalog systemCatalogReference = new NextCatalog();
			systemCatalogReference.setId(XMLCorePlugin.SYSTEM_CATALOG_ID);
			systemCatalogReference.setCatalogLocation(SYSTEM_CATALOG_FILE);
			addCatalogElement(systemCatalogReference);

			/*
			 * Here we save the file in order to 'reflect' the catalog that
			 * we've created from plug-in extensions to disk. The 'default'
			 * catalog is only ever written to disk and never read from disk.
			 */
			save();
		}
	}

	class InternalResolver
	{
		protected Map publicMap = new HashMap();

		protected Map systemMap = new HashMap();

		protected Map uriMap = new HashMap();

		InternalResolver()
		{
			for (Iterator i = catalogElements.iterator(); i.hasNext();)
			{
				ICatalogElement catalogElement = (ICatalogElement) i.next();
				if (catalogElement.getType() == ICatalogElement.TYPE_ENTRY)
				{
					ICatalogEntry entry = (ICatalogEntry) catalogElement;
					Map map = getEntryMap(entry.getEntryType());
					map.put(entry.getKey(), entry);
				}
			}
		}

		private Map getEntryMap(int entryType)
		{
			Map map = systemMap;
			switch (entryType)
			{
			case ICatalogEntry.ENTRY_TYPE_PUBLIC:
				map = publicMap;
				break;
			case ICatalogEntry.ENTRY_TYPE_URI:
				map = uriMap;
				break;
			default:
				break;
			}
			return map;
		}

		protected String getMappedURI(Map map, String key)
		{
			CatalogEntry entry = (CatalogEntry) map.get(key);
			if(entry == null) return null;
			String uri = entry.getURI();
			try
			{
                // TODO CS : do we really want to resolve these here?
                // I'm guessing we should return the 'platform:' form of the URI
                // to the caller.
                if (uri.startsWith("platform:")) //$NON-NLS-1$
                {  
				  URL entryURL = new URL(entry.getAbsolutePath(uri));                
				  uri = Platform.resolve(entryURL).toString();
                  
                  // we need to ensure URI's are of form "file:///D:/XXX" and NOT  
                  // "file:D:/XXX".  Otherwise the EMF URI class gets confused
                  // (see bug 103607) 
                  String FILE_SCHEME = "file:"; //$NON-NLS-1$
                  if (uri.startsWith(FILE_SCHEME) && !uri.startsWith(FILE_SCHEME + "/")) //$NON-NLS-1$
                  {
                    uri = FILE_SCHEME + "///" + uri.substring(FILE_SCHEME.length()); //$NON-NLS-1$
                  }  
                }  
                return uri; 
			} catch (IOException e)
			{
				return null;
			}
		}

		public String resolvePublic(String publicId, String systemId)
				throws MalformedURLException, IOException
		{
			String result = getMappedURI(publicMap, publicId);
			if (result == null)
			{
				result = getMappedURI(systemMap, systemId);
			}
			// our clients used to pass namespace in place of public id, so we need to check uri map for those
			if (result == null)
			{
				result = getMappedURI(uriMap, publicId);
			}
			if (result == null)
			{
				result = resolveSubordinateCatalogs(
						ICatalogEntry.ENTRY_TYPE_PUBLIC, publicId, systemId);
			}
			return result;
		}

		public String resolveSystem(String systemId)
				throws MalformedURLException, IOException
		{
			String result = getMappedURI(systemMap, systemId);
			if (result == null)
			{
				result = resolveSubordinateCatalogs(
						ICatalogEntry.ENTRY_TYPE_SYSTEM, null, systemId);
			}
			return result;
		}

		public String resolveURI(String uri) throws MalformedURLException,
				IOException
		{
			String result = getMappedURI(uriMap, uri);
			if (result == null)
			{
				result = resolveSubordinateCatalogs(
						ICatalogEntry.ENTRY_TYPE_URI, null, uri);
			}
			return result;
		}
	}

	class SystemCatalogLS extends CatalogLS
	{
		public void load()
		{
			new CatalogContributorRegistryReader(Catalog.this).readRegistry();

			/*
			 * Here we save the file in order to 'reflect' the catalog that
			 * we've created from plugin extensions to disk. 
			 * The 'system' catalog is only ever written to disk and never read from disk.
			 */
			save();
		}
	}

	class UserCatalogLS extends CatalogLS
	{
		public void load()
		{
			InputStream inputStream = null;
			try
			{
				URL url = new URL(location);
				inputStream = url.openStream();
				boolean oldNotificationEnabled = isNotificationEnabled();
				setNotificationEnabled(false);
				clear();
				try
				{
					CatalogReader.read(Catalog.this, inputStream);
				} finally
				{
					setNotificationEnabled(oldNotificationEnabled);
				}
				notifyChanged();
			} catch (Exception e)
			{
			} finally
			{
				if (inputStream != null)
				{
					try
					{
						inputStream.close();
					} catch (Exception e)
					{
					}
				}
			}
		}
	}

	public static final String DEFAULT_CATALOG_FILE = "default_catalog.xml"; //$NON-NLS-1$

	public static final String SYSTEM_CATALOG_FILE = "system_catalog.xml"; //$NON-NLS-1$

	public static final String USER_CATALOG_FILE = "user_catalog.xml"; //$NON-NLS-1$

	protected String base;

	protected List catalogElements = new ArrayList();

	protected CatalogLS catalogLS;

	protected String id;

	protected InternalResolver internalResolver;

	protected boolean isNotificationEnabled;

	protected List listenerList = new ArrayList();

	protected String location;

	protected CatalogSet resourceSet;

	public Catalog(CatalogSet catalogResourceSet, String id, String location)
	{
		this.resourceSet = catalogResourceSet;
		this.id = id;
		this.location = location;

		if (XMLCorePlugin.DEFAULT_CATALOG_ID.equals(id))
		{
			catalogLS = new DefaultCatalogLS();
		} else if (XMLCorePlugin.SYSTEM_CATALOG_ID.equals(id))
		{
			catalogLS = new SystemCatalogLS();
		} else
		{
			catalogLS = new UserCatalogLS();
		}
	}

	public void addCatalogElement(ICatalogElement element)
	{
		catalogElements.add(element);
		element.setOwnerCatalog(this);
		internalResolver = null;
		notifyAddElement(element);
	}

	public void addEntriesFromCatalog(ICatalog catalog)
	{
		try
		{
			setNotificationEnabled(false);
			if (catalog != null)
			{
				ICatalogElement[] entries = ((Catalog)catalog).getCatalogElements();
				for (int i = 0; i < entries.length; i++)
				{
					CatalogElement clone = (CatalogElement)((CatalogElement)entries[i]).clone();
					addCatalogElement(clone);
				}
			} else
			{
				Logger.log(Logger.ERROR, "argument was null in Catalog.addEntriesFromCatalog"); //$NON-NLS-1$
			}
		} finally
		{
			setNotificationEnabled(true);
		}
		internalResolver = null;
		notifyChanged();
	}

	public void addListener(ICatalogListener listener)
	{
		listenerList.add(listener);
	}

	public void clear()
	{
		catalogElements.clear();
		internalResolver = null;
		notifyChanged();
	}

	public ICatalogElement createCatalogElement(int type)
	{
		switch (type)
		{
		case ICatalogElement.TYPE_ENTRY:
			return new CatalogEntry();
		case ICatalogElement.TYPE_NEXT_CATALOG:
			return new NextCatalog();
		case ICatalogEntry.ENTRY_TYPE_PUBLIC:
			return new CatalogEntry(ICatalogEntry.ENTRY_TYPE_PUBLIC);
		case ICatalogEntry.ENTRY_TYPE_SYSTEM:
			return new CatalogEntry(ICatalogEntry.ENTRY_TYPE_SYSTEM);
		case ICatalogEntry.ENTRY_TYPE_URI:
			return new CatalogEntry(ICatalogEntry.ENTRY_TYPE_URI);
		default:
			return new CatalogElement(type);
		}
	}

	public String getBase()
	{
		return base;
	}

	private List getCatalogElements(int type)
	{
		List result = new ArrayList();
		ICatalogElement[] elements = (ICatalogElement[]) catalogElements
				.toArray(new ICatalogElement[catalogElements.size()]);
		for (int i = 0; i < elements.length; i++)
		{
			ICatalogElement element = elements[i];
			if (element.getType() == type)
			{
				result.add(element);
			}
		}
		return result;
	}

	public ICatalogEntry[] getCatalogEntries()
	{
		List result = getCatalogElements(ICatalogElement.TYPE_ENTRY);
		return (ICatalogEntry[]) result
				.toArray(new ICatalogEntry[result.size()]);
	}

	protected CatalogSet getCatalogSet()
	{
		return resourceSet;
	}

	public String getId()
	{
		return id;
	}

	public String getLocation()
	{
		return location;
	}

	public INextCatalog[] getNextCatalogs()
	{
		List result = getCatalogElements(ICatalogElement.TYPE_NEXT_CATALOG);
		return (INextCatalog[]) result.toArray(new INextCatalog[result.size()]);
	}

	protected InternalResolver getOrCreateInternalResolver()
	{
		if (internalResolver == null)
		{
			internalResolver = new InternalResolver();
		}
		return internalResolver;
	}

	protected boolean isNotificationEnabled()
	{
		return isNotificationEnabled;
	}

	public void load() throws IOException
	{
		catalogLS.load();
	}

	protected void notifyAddElement(ICatalogElement entry)
	{
		if (isNotificationEnabled)
		{
			ICatalogEvent event = new CatalogEvent(this, entry,
					ICatalogEvent.ELEMENT_ADDED);
			notifyListeners(event);
		}
	}

	protected void notifyChanged()
	{
		ICatalogEvent event = new CatalogEvent(this, null,
				ICatalogEvent.CHANGED);
		notifyListeners(event);
	}

	protected void notifyListeners(ICatalogEvent event)
	{
		List list = new ArrayList();
		list.addAll(listenerList);
		for (Iterator i = list.iterator(); i.hasNext();)
		{
			ICatalogListener listener = (ICatalogListener) i.next();
			listener.catalogChanged(event);
		}
	}

	protected void notifyRemoveElement(ICatalogElement element)
	{
		if (isNotificationEnabled)
		{
			ICatalogEvent event = new CatalogEvent(this, element,
					ICatalogEvent.ELEMENT_REMOVED);
			notifyListeners(event);
		}
	}

	public void removeCatalogElement(ICatalogElement element)
	{
		catalogElements.remove(element);
		internalResolver = null;
		notifyRemoveElement(element);
		
	}

	public void removeListener(ICatalogListener listener)
	{
		listenerList.remove(listener);
	}

	public String resolvePublic(String publicId, String systemId)
			throws MalformedURLException, IOException
	{
		return getOrCreateInternalResolver().resolvePublic(publicId, systemId);
	}

	protected String resolveSubordinateCatalogs(int entryType, String publicId,
			String systemId) throws MalformedURLException, IOException
	{
		String result = null;
		INextCatalog[] nextCatalogs = getNextCatalogs();
		for (int i = 0; i < nextCatalogs.length; i++)
		{
			INextCatalog nextCatalog = nextCatalogs[i];
			ICatalog catalog = nextCatalog.getReferencedCatalog();
			if (catalog != null)
			{
				switch (entryType)
				{
				case ICatalogEntry.ENTRY_TYPE_PUBLIC:
					result = catalog.resolvePublic(publicId, systemId);
					break;
				case ICatalogEntry.ENTRY_TYPE_SYSTEM:
					result = catalog.resolveSystem(systemId);
					break;
				case ICatalogEntry.ENTRY_TYPE_URI:
					result = catalog.resolveURI(systemId);
					break;
				default:
					break;
				}
				if (result != null)
				{
					return result;
				}
			}
		}
		return null;
	}

	public String resolveSystem(String systemId) throws MalformedURLException,
			IOException
	{
		return getOrCreateInternalResolver().resolveSystem(systemId);
	}

	public String resolveURI(String uri) throws MalformedURLException,
			IOException
	{
		return getOrCreateInternalResolver().resolveURI(uri);
	}

	public void save() throws IOException
	{
		catalogLS.save();
	}

	public void setBase(String base)
	{
		this.base = base;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public void setLocation(String location)
	{
		this.location = location;
	}

	protected void setNotificationEnabled(boolean b)
	{
		isNotificationEnabled = b;
	}

	public ICatalogElement[] getCatalogElements()
	{
		return (ICatalogElement[]) catalogElements.toArray(new ICatalogElement[catalogElements.size()]);
	}
	

	

}
