/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.internal.variables;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.IDynamicVariable;
import org.eclipse.core.variables.IStringVariable;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.IValueVariable;
import org.eclipse.core.variables.IValueVariableListener;
import org.eclipse.core.variables.VariablesPlugin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Singleton string variable manager. 
 */
public class StringVariableManager implements IStringVariableManager {
	
	/**
	 * Dynamic variables - maps variable names to variables.
	 */
	private Map fDynamicVariables;
	
	/**
	 * Value varialbes - maps variable names to variables.
	 */
	private Map fValueVariables;
	
	/**
	 * Variable listeners
	 */
	private ListenerList fListeners;
	
	// notifications
	private static final int ADDED = 0;
	private static final int CHANGED = 1;
	private static final int REMOVED = 2;
	
	/**
	 * Singleton variable manager.
	 */
	private static StringVariableManager fgManager; 
	
	// true during initialization code - supress change notification
	private boolean fInitializing = false;
	
	// Variable extension point constants
	private static final String ATTR_NAME= "name"; //$NON-NLS-1$
	private static final String ATTR_DESCRIPTION="description"; //$NON-NLS-1$	
	// Persisted variable XML constants
	private static final String VALUE_VARIABLES_TAG= "valueVariables"; //$NON-NLS-1$
	private static final String VALUE_VARIABLE_TAG= "valueVariable"; //$NON-NLS-1$
	private static final String NAME_TAG= "name"; //$NON-NLS-1$
	private static final String VALUE_TAG= "value"; //$NON-NLS-1$
	private static final String DESCRIPTION_TAG="description"; //$NON-NLS-1$
	private static final String INITIALIZED_TAG="contributed"; //$NON-NLS-1$
	// XML values
	private static final String TRUE_VALUE= "true"; //$NON-NLS-1$
	private static final String FALSE_VALUE= "false"; //$NON-NLS-1$
	// preference store key for value variables
	private static final String PREF_VALUE_VARIABLES= VariablesPlugin.getUniqueIdentifier() + ".valueVariables"; //$NON-NLS-1$	
		
	/**
	 * Notifies a string variable listener in a safe runnable to handle
	 * exceptions.
	 */
	class StringVariableNotifier implements ISafeRunnable {
		
		private IValueVariableListener fListener;
		private int fType;
		private IValueVariable[] fVariables;
		
		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		public void handleException(Throwable exception) {
			IStatus status = new Status(IStatus.ERROR, VariablesPlugin.getUniqueIdentifier(), VariablesPlugin.INTERNAL_ERROR, "An exception occurred during string variable change notification", exception); //$NON-NLS-1$
			VariablesPlugin.log(status);
		}

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		public void run() throws Exception {
			switch (fType) {
				case ADDED:
					fListener.variablesAdded(fVariables);
					break;
				case REMOVED:
					fListener.variablesRemoved(fVariables);
					break;
				case CHANGED:
					fListener.variablesChanged(fVariables);
					break;
			}			
		}

		/**
		 * Notifies the given listener of the add/change/remove
		 * 
		 * @param listener the listener to notify
		 * @param launch the launch that has changed
		 * @param update the type of change
		 */
		public void notify(IValueVariable[] variables, int update) {
			fVariables = variables;
			fType = update;
			Object[] copiedListeners= fListeners.getListeners();
			for (int i= 0; i < copiedListeners.length; i++) {
				fListener = (IValueVariableListener)copiedListeners[i];
				Platform.run(this);
			}	
			fVariables = null;
			fListener = null;
			// persist variables whenever there is an add/change/remove	
			storeValueVariables();	
		}
	}	
	
	/**
	 * Returns a new notifier.
	 * 
	 * @return a new notifier
	 */
	private StringVariableNotifier getNotifier() {
		return new StringVariableNotifier();
	}
	
	/**
	 * Returns the default string variable manager
	 * 
	 * @return string variable manager
	 */
	public static StringVariableManager getDefault() {
		if (fgManager == null) {
			fgManager = new StringVariableManager();
		}
		return fgManager;
	}
	
	/**
	 * Constructs a new string variable manager. 
	 */
	private StringVariableManager() {
		fListeners = new ListenerList(5);
	}	

	/**
	 * Load contributed variables and persisted variables
	 */
	private void initialize() {
		if (fDynamicVariables == null) {
			fInitializing = true;
			fDynamicVariables = new HashMap(5);
			fValueVariables = new HashMap(5);
			loadPersistedValueVariables();
			loadContributedValueVariables();
			loadDynamicVariables();
			fInitializing = false;
		}
	}
	
	/**
	 * Loads contributed dynamic variables
	 */
	private void loadDynamicVariables() {
		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(VariablesPlugin.PI_CORE_VARIABLES, EXTENSION_POINT_DYNAMIC_VARIABLES);
		IConfigurationElement elements[]= point.getConfigurationElements();
		for (int i = 0; i < elements.length; i++) {
			IConfigurationElement element = elements[i];
			String name= element.getAttribute(ATTR_NAME);
			if (name == null) {
				VariablesPlugin.logMessage(MessageFormat.format("Variable extension missing required 'name' attribute: {0}", new String[] {element.getDeclaringExtension().getLabel()}), null); //$NON-NLS-1$
				continue;
			}
			String description= element.getAttribute(ATTR_DESCRIPTION);
			DynamicVariable variable= new DynamicVariable(name, description, element);
			fDynamicVariables.put(variable.getName(), variable);
		}
	}

	/**
	 * Loads any persisted value varialbes from the preference store.
	 */
	private void loadPersistedValueVariables() {
		String variablesString= VariablesPlugin.getDefault().getPluginPreferences().getString(PREF_VALUE_VARIABLES);
		if (variablesString.length() == 0) {
			return;
		}
		Element root= null;
		Throwable ex = null;
		try {
			ByteArrayInputStream stream = new ByteArrayInputStream(variablesString.getBytes("UTF-8")); //$NON-NLS-1$
			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			parser.setErrorHandler(new DefaultHandler());
			root = parser.parse(stream).getDocumentElement();
		} catch (UnsupportedEncodingException e) {
			ex = e;
		} catch (ParserConfigurationException e) {
			ex = e;
		} catch (FactoryConfigurationError e) {
			ex = e;
		} catch (SAXException e) {
			ex = e;
		} catch (IOException e) {
			ex = e;
		}
		if (ex != null) {
			VariablesPlugin.logMessage("An exception occurred while loading persisted value variables.", ex); //$NON-NLS-1$
			return;
		}
		if (!root.getNodeName().equals(VALUE_VARIABLES_TAG)) {
			VariablesPlugin.logMessage("Invalid format encountered while loading persisted value variables.", null); //$NON-NLS-1$
			return;
		}
		NodeList list= root.getChildNodes();
		for (int i= 0, numItems= list.getLength(); i < numItems; i++) {
			Node node= list.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				Element element= (Element) node;
				if (!element.getNodeName().equals(VALUE_VARIABLE_TAG)) {
					VariablesPlugin.logMessage(MessageFormat.format("Invalid XML element encountered while loading value variables: {0}", new String[] {node.getNodeName()}), null); //$NON-NLS-1$
					continue;
				}
				String name= element.getAttribute(NAME_TAG);
				if (name.length() > 0) {
					String value= element.getAttribute(VALUE_TAG);
					String description= element.getAttribute(DESCRIPTION_TAG);
					boolean initialized= TRUE_VALUE.equals(element.getAttribute(INITIALIZED_TAG));
					ValueVariable variable= new ValueVariable(name, description, null);
					if (initialized) {
						variable.setValue(value);
					}
					fValueVariables.put(name, variable);
				} else {
					VariablesPlugin.logMessage("Invalid variable entry encountered while loading value variables. Variable name is null.", null); //$NON-NLS-1$
				}
			}
		}		
	}

	/**
	 * Loads contributed value variables. This is done after the persisted value
	 * varaibles are restored. Any contributed variables with the same name are
	 * merged with existing persisted values.
	 */
	private void loadContributedValueVariables() {
		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(VariablesPlugin.PI_CORE_VARIABLES, EXTENSION_POINT_VALUE_VARIABLES);
		IConfigurationElement elements[]= point.getConfigurationElements();
		for (int i = 0; i < elements.length; i++) {
			IConfigurationElement element = elements[i];
			String name= element.getAttribute(ATTR_NAME);
			if (name == null) {
				VariablesPlugin.logMessage(MessageFormat.format("Variable extension missing required 'name' attribute: {0}", new String[] {element.getDeclaringExtension().getLabel()}), null); //$NON-NLS-1$
				continue;
			}
			String description= element.getAttribute(ATTR_DESCRIPTION);
			ValueVariable variable= new ValueVariable(name, description, element);
			// if already present, merge with persisted value
			ValueVariable existing = (ValueVariable)getValueVariable(name);
			if (existing != null) {
				if (existing.isInitialized()) {
					variable.setValue(existing.getValue());
				}					
			}
			fValueVariables.put(variable.getName(), variable);
		}		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#getVariables()
	 */
	public IStringVariable[] getVariables() {
		initialize();
		List list = new ArrayList(fDynamicVariables.size() + fValueVariables.size());
		list.addAll(fDynamicVariables.values());
		list.addAll(fValueVariables.values());
		return (IStringVariable[]) list.toArray(new IStringVariable[list.size()]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#getValueVariables()
	 */
	public IValueVariable[] getValueVariables() {
		initialize();
		return (IValueVariable[]) fValueVariables.values().toArray(new IValueVariable[fValueVariables.size()]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#getDynamicVariables()
	 */
	public IDynamicVariable[] getDynamicVariables() {
		initialize();
		return (IDynamicVariable[]) fDynamicVariables.values().toArray(new IDynamicVariable[fDynamicVariables.size()]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#performStringSubstitution(java.lang.String)
	 */
	public String performStringSubstitution(String expression) throws CoreException {
		return performStringSubstitution(expression, true);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#newValueVariable(java.lang.String, java.lang.String)
	 */
	public IValueVariable newValueVariable(String name, String description) {
		IConfigurationElement element = null;
		ValueVariable existing = (ValueVariable)getValueVariable(name);
		if (existing != null && existing.isContributed()) {
			element = existing.getConfigurationElement();
		}
		return new ValueVariable(name, description, element);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#addVariables(org.eclipse.debug.internal.core.stringsubstitution.IValueVariable[])
	 */
	public void addVariables(IValueVariable[] variables) throws CoreException {
		initialize();
		MultiStatus status = new MultiStatus(VariablesPlugin.getUniqueIdentifier(), VariablesPlugin.INTERNAL_ERROR, VariablesMessages.getString("StringVariableManager.26"), null); //$NON-NLS-1$
		for (int i = 0; i < variables.length; i++) {
			IValueVariable variable = variables[i];
			if (getValueVariable(variable.getName()) != null) {
				status.add(new Status(IStatus.ERROR, VariablesPlugin.getUniqueIdentifier(), VariablesPlugin.INTERNAL_ERROR, MessageFormat.format(VariablesMessages.getString("StringVariableManager.27"), new String[]{variable.getName()}), null)); //$NON-NLS-1$
			}			
		}
		if (status.isOK()) {
			for (int i = 0; i < variables.length; i++) {
				IValueVariable variable = variables[i];
				fValueVariables.put(variable.getName(), variable);
			}
			IValueVariable[] copy = new IValueVariable[variables.length];
			System.arraycopy(variables, 0, copy, 0, variables.length);
			getNotifier().notify(copy, ADDED);
			return;
		}
		throw new CoreException(status);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#removeVariables(org.eclipse.debug.internal.core.stringsubstitution.IValueVariable[])
	 */
	public void removeVariables(IValueVariable[] variables) {
		initialize();
		List removed = new ArrayList(variables.length);
		for (int i = 0; i < variables.length; i++) {
			IValueVariable variable = variables[i];
			if (fValueVariables.remove(variable.getName()) != null) {
				removed.add(variable);
			}
		}
		if (removed.size() > 0) {
			getNotifier().notify((IValueVariable[])removed.toArray(new IValueVariable[removed.size()]), REMOVED);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#getDynamicVariable(java.lang.String)
	 */
	public IDynamicVariable getDynamicVariable(String name) {
		initialize();
		return (IDynamicVariable) fDynamicVariables.get(name);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#getValueVariable(java.lang.String)
	 */
	public IValueVariable getValueVariable(String name) {
		initialize();
		return (IValueVariable) fValueVariables.get(name);
	}


	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#addValueVariableListener(org.eclipse.debug.internal.core.stringsubstitution.IValueVariableListener)
	 */
	public void addValueVariableListener(IValueVariableListener listener) {
		fListeners.add(listener);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#removeValueVariableListener(org.eclipse.debug.internal.core.stringsubstitution.IValueVariableListener)
	 */
	public void removeValueVariableListener(IValueVariableListener listener) {
		fListeners.remove(listener);
	}
	
	/**
	 * Returns a memento representing the value variables currently registered.
	 * 
	 * @return memento representing the value variables currently registered
	 * @throws IOException if an I/O exception occurs while creating the XML.
	 */
	private String getValueVariablesAsXML() throws IOException, ParserConfigurationException, TransformerException {
		IValueVariable[] variables = getValueVariables();

		Document document= getDocument();
		Element rootElement= document.createElement(VALUE_VARIABLES_TAG);
		document.appendChild(rootElement);
		for (int i = 0; i < variables.length; i++) {
			ValueVariable variable = (ValueVariable)variables[i];
			Element element= document.createElement(VALUE_VARIABLE_TAG);
			element.setAttribute(NAME_TAG, variable.getName());
			String value= variable.getValue();
			if (value != null) {
				element.setAttribute(VALUE_TAG, value);
			}
			String description= variable.getDescription();
			if (description != null) {
				element.setAttribute(DESCRIPTION_TAG, description);
			}
			element.setAttribute(INITIALIZED_TAG, variable.isInitialized() ? TRUE_VALUE : FALSE_VALUE);
			rootElement.appendChild(element);
		}
		return serializeDocument(document);
	}
	
	private Document getDocument() throws ParserConfigurationException {
		DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
		Document doc =docBuilder.newDocument();
		return doc;
	}
	
	/**
	 * Serializes a XML document into a string - encoded in UTF8 format,
	 * with platform line separators.
	 * 
	 * @param doc document to serialize
	 * @return the document as a string
	 * @throws TransformerException if an unrecoverable error occurs during the serialization
	 * @throws IOException if the encoding attempted to be used is not supported
	 */
	private String serializeDocument(Document doc) throws TransformerException, UnsupportedEncodingException {
		ByteArrayOutputStream s= new ByteArrayOutputStream();
		
		TransformerFactory factory= TransformerFactory.newInstance();
		Transformer transformer= factory.newTransformer();
		transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
		transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
		
		DOMSource source= new DOMSource(doc);
		StreamResult outputTarget= new StreamResult(s);
		transformer.transform(source, outputTarget);
		
		return s.toString("UTF8"); //$NON-NLS-1$			
	}
	
	/**
	 * Saves the value variables currently registered in the
	 * preference store. 
	 */
	private void storeValueVariables() {
		Preferences prefs= VariablesPlugin.getDefault().getPluginPreferences();
		String variableString= ""; //$NON-NLS-1$
		if (!fValueVariables.isEmpty()) {
			try {
				variableString= getValueVariablesAsXML();
			} catch (IOException e) {
				VariablesPlugin.log(new Status(IStatus.ERROR, VariablesPlugin.getUniqueIdentifier(), IStatus.ERROR, "An exception occurred while storing launch configuration variables.", e)); //$NON-NLS-1$
				return;
			} catch (ParserConfigurationException e) {
				VariablesPlugin.log(new Status(IStatus.ERROR, VariablesPlugin.getUniqueIdentifier(), IStatus.ERROR, "An exception occurred while storing launch configuration variables.", e)); //$NON-NLS-1$
				return;
			} catch (TransformerException e) {
				VariablesPlugin.log(new Status(IStatus.ERROR, VariablesPlugin.getUniqueIdentifier(), IStatus.ERROR, "An exception occurred while storing launch configuration variables.", e)); //$NON-NLS-1$
				return;
			}
		}
		prefs.setValue(PREF_VALUE_VARIABLES, variableString);
		VariablesPlugin.getDefault().savePluginPreferences();
	}

	/**
	 * Fire a change notification for the given variable.
	 * 
	 * @param variable the variable that has changed
	 */
	protected void notifyChanged(ValueVariable variable) {
		if (!fInitializing) {
			IValueVariable existing = getValueVariable(variable.getName());
			if (variable.equals(existing)) {
				// do not do change notification for unregistered variables
				getNotifier().notify(new IValueVariable[]{variable}, CHANGED);
			}
		}
	}	

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#generateVariableExpression(java.lang.String, java.lang.String)
	 */
	public String generateVariableExpression(String varName, String arg) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("${"); //$NON-NLS-1$
		buffer.append(varName);
		if (arg != null) {
			buffer.append(":"); //$NON-NLS-1$
			buffer.append(arg);
		}
		buffer.append("}"); //$NON-NLS-1$
		return buffer.toString();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.stringsubstitution.IStringVariableManager#performStringSubstitution(java.lang.String, boolean)
	 */
	public String performStringSubstitution(String expression,	boolean reportUndefinedVariables) throws CoreException {
		return new StringSubstitutionEngine().performStringSubstitution(expression, reportUndefinedVariables, true, this);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.variables.IStringVariableManager#validateStringVariables(java.lang.String)
	 */
	public void validateStringVariables(String expression) throws CoreException {
		new StringSubstitutionEngine().validateStringVariables(expression, this);
	}

    /* (non-Javadoc)
     * @see org.eclipse.core.variables.IStringVariableManager#getContributingPluginId(org.eclipse.core.variables.IStringVariable)
     */
    public String getContributingPluginId(IStringVariable variable) {
        if (variable instanceof StringVariable) {
            return ((StringVariable) variable).getConfigurationElement().getNamespace();
        }
        return null;
    }
}
