/*******************************************************************************
 * Copyright (c) 2005, 2007 BEA Systems, Inc. 
 * 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:
 *    jgarms@bea.com - initial API and implementation
 *    
 *******************************************************************************/
package org.eclipse.jdt.apt.core.internal.util;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.apt.core.internal.AptPlugin;
import org.eclipse.jdt.apt.core.internal.ExtJarFactoryContainer;
import org.eclipse.jdt.apt.core.internal.FactoryPluginManager;
import org.eclipse.jdt.apt.core.internal.VarJarFactoryContainer;
import org.eclipse.jdt.apt.core.internal.WkspJarFactoryContainer;
import org.eclipse.jdt.apt.core.internal.util.FactoryContainer.FactoryType;
import org.eclipse.jdt.apt.core.util.IFactoryPath;
import org.eclipse.jdt.core.IJavaProject;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Utility class for dealing with the factory path
 */
public final class FactoryPathUtil {
	
	private static final String FACTORYPATH_TAG = "factorypath"; //$NON-NLS-1$
	private static final String FACTORYPATH_ENTRY_TAG = "factorypathentry"; //$NON-NLS-1$
	private static final String KIND = "kind"; //$NON-NLS-1$
	private static final String ID = "id"; //$NON-NLS-1$
	private static final String ENABLED = "enabled"; //$NON-NLS-1$
	private static final String RUN_IN_BATCH_MODE = "runInBatchMode"; //$NON-NLS-1$
	
	private static final String FACTORYPATH_FILE = ".factorypath"; //$NON-NLS-1$
	
	// four spaces for indent
	private static final String INDENT = "    "; //$NON-NLS-1$

	// Private c-tor to prevent construction
	private FactoryPathUtil() {}
	
	/**
	 * Test whether a resource is a factory path file.  The criteria are
	 * that it is a file, it belongs to a project, it is located in the root 
	 * of that project, and it is named ".factorypath".  Note that the 
	 * workspace-wide factorypath file does NOT meet these criteria.
	 * @param res any sort of IResource, or null.
	 * @return true if the resource is a project-specific factory path file.
	 */
	public static boolean isFactoryPathFile(IResource res) {
		if (res == null || res.getType() != IResource.FILE || res.getProject() == null) {
			return false;
		}
		IPath path = res.getProjectRelativePath();
		if (path.segmentCount() != 1) {
			return false;
		}
		return FACTORYPATH_FILE.equals(path.lastSegment());
	}
	
	/**
	 * Loads a map of factory containers from the factory path for a given
	 * project. If no factorypath file was found, returns null.
	 */
	public static Map<FactoryContainer, FactoryPath.Attributes> readFactoryPathFile(IJavaProject jproj) 
		throws CoreException
	{
		String data = null;
		try {
			// If project is null, use workspace-level data
			if (jproj == null) {
				File file = getFileForWorkspace();
				if (!file.exists()) {
					return null;
				}
				data = FileSystemUtil.getContentsOfFile(file);
			}
			else {
				IFile ifile = getIFileForProject(jproj);
				if (!ifile.exists()) {
					return null;
				}
				data = FileSystemUtil.getContentsOfIFile(ifile);
			}
		}
		catch (IOException e) {
			throw new CoreException(new Status(IStatus.ERROR, AptPlugin.PLUGIN_ID, -1, Messages.FactoryPathUtil_status_ioException, e));
		}
		
		return FactoryPathUtil.decodeFactoryPath(data);
	}
	
	/**
	 * Stores a map of factory containers to the factorypath file
	 * for a given project. If null is passed in, the factorypath file
	 * is deleted.
	 */
	public static void saveFactoryPathFile(IJavaProject jproj, Map<FactoryContainer, FactoryPath.Attributes> containers) 
		throws CoreException 
	{
		IFile projFile;
		File wkspFile;
		if (jproj != null) {
			projFile = getIFileForProject(jproj);
			wkspFile = null;
		}
		else {
			wkspFile = getFileForWorkspace();
			projFile = null;
		}
		
		try {
			if (containers != null) {
				String data = FactoryPathUtil.encodeFactoryPath(containers);
				// If project is null, set workspace-level data
				if (jproj == null) {
					FileSystemUtil.writeStringToFile(wkspFile, data);
				}
				else {
					FileSystemUtil.writeStringToIFile(projFile, data);
				}
			}
			else { // restore defaults by deleting the factorypath file.
				if (jproj != null) {
					projFile.delete(true, null);
				}
				else {
					wkspFile.delete();
				}
			}
		}
		catch (IOException e) {
			throw new CoreException(new Status(IStatus.ERROR, AptPlugin.PLUGIN_ID, -1, Messages.FactoryPathUtil_status_ioException, e));
		}
	}
	
	/**
	 * Returns an XML string encoding all of the factories.
	 * @param factories
	 */
	public static String encodeFactoryPath(Map<FactoryContainer, FactoryPath.Attributes> factories) {
		StringBuilder sb = new StringBuilder();
		sb.append("<").append(FACTORYPATH_TAG).append(">\n"); //$NON-NLS-1$ //$NON-NLS-2$
		for (Map.Entry<FactoryContainer, FactoryPath.Attributes> entry : factories.entrySet()) {
			FactoryContainer container = entry.getKey();
			FactoryPath.Attributes attr = entry.getValue();
			sb.append(INDENT);
			sb.append("<"); //$NON-NLS-1$
			sb.append(FACTORYPATH_ENTRY_TAG).append(" "); //$NON-NLS-1$
			sb.append(KIND).append("=\"").append(container.getType()).append("\" "); //$NON-NLS-1$ //$NON-NLS-2$
			sb.append(ID).append("=\"").append(container.getId()).append("\" "); //$NON-NLS-1$ //$NON-NLS-2$
			sb.append(ENABLED).append("=\"").append(attr.isEnabled()).append("\" "); //$NON-NLS-1$ //$NON-NLS-2$
			sb.append(RUN_IN_BATCH_MODE).append("=\"").append(attr.runInBatchMode()).append("\"/>\n"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		sb.append("</").append(FACTORYPATH_TAG).append(">\n"); //$NON-NLS-1$ //$NON-NLS-2$
		
		return sb.toString();
	}
	
	/**
	 * Create a factory container based on an external jar file (not in the 
	 * workspace).
	 * @param jar a java.io.File representing the jar file.
	 */
	public static FactoryContainer newExtJarFactoryContainer(File jar) {
		return new ExtJarFactoryContainer(jar);
	}
	
	/**
	 * Create a factory container based on a jar file in the workspace.
	 * @param jar an Eclipse IPath representing the jar file; the path is
	 * relative to the workspace root.
	 */
	public static FactoryContainer newWkspJarFactoryContainer(IPath jar) {
		return new WkspJarFactoryContainer(jar);
	}
	
	/**
	 * Create a factory container based on an external jar file specified 
	 * by a classpath variable (and possibly a path relative to that variable).
	 * @param jar an Eclipse IPath representing the jar file; the first
	 * segment of the path is assumed to be the variable name.
	 */
	public static FactoryContainer newVarJarFactoryContainer(IPath jar) {
		return new VarJarFactoryContainer(jar);
	}

	public static Map<FactoryContainer, FactoryPath.Attributes> decodeFactoryPath(final String xmlFactoryPath) 
	throws CoreException
	{
		Map<FactoryContainer, FactoryPath.Attributes> result = new LinkedHashMap<FactoryContainer, FactoryPath.Attributes>();
		StringReader reader = new StringReader(xmlFactoryPath);
		Element fpElement = null;

		try {
			DocumentBuilder parser = 
				DocumentBuilderFactory.newInstance().newDocumentBuilder();
			fpElement = parser.parse(new InputSource(reader)).getDocumentElement();

		}
		catch (IOException e) {
			throw new CoreException(new Status(IStatus.ERROR, AptPlugin.PLUGIN_ID, -1, Messages.FactoryPathUtil_status_ioException, e));
		}
		catch (SAXException e) {
			throw new CoreException(new Status(IStatus.ERROR, AptPlugin.PLUGIN_ID, -1, Messages.FactoryPathUtil_status_couldNotParse, e));
		}
		catch (ParserConfigurationException e) {
			throw new CoreException(new Status(IStatus.ERROR, AptPlugin.PLUGIN_ID, -1, Messages.FactoryPathUtil_status_parserConfigError, e));
		}
		finally {
			reader.close();
		}

		if (!fpElement.getNodeName().equalsIgnoreCase(FACTORYPATH_TAG)) {
			IOException e = new IOException("Incorrect file format. File must begin with " + FACTORYPATH_TAG); //$NON-NLS-1$
			throw new CoreException(new Status(IStatus.ERROR, AptPlugin.PLUGIN_ID, -1, Messages.FactoryPathUtil_status_ioException, e));
		}
		NodeList nodes = fpElement.getElementsByTagName(FACTORYPATH_ENTRY_TAG);
		for (int i=0; i < nodes.getLength(); i++) {
			Node node = nodes.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				Element element = (Element)node;
				String kindString = element.getAttribute(KIND);
				// deprecated container type "JAR" is now "EXTJAR"
				if ("JAR".equals(kindString)) { //$NON-NLS-1$
					kindString = "EXTJAR"; //$NON-NLS-1$
				}
				String idString = element.getAttribute(ID);
				String enabledString = element.getAttribute(ENABLED);
				String runInAptModeString = element.getAttribute(RUN_IN_BATCH_MODE); 
				FactoryType kind = FactoryType.valueOf(kindString);
				FactoryContainer container = null;
				switch (kind) {

				case WKSPJAR :
					container = newWkspJarFactoryContainer(new Path(idString));
					break;

				case EXTJAR :
					container = newExtJarFactoryContainer(new File(idString));
					break;

				case VARJAR :
					container = newVarJarFactoryContainer(new Path(idString));
					break;

				case PLUGIN :
					container = FactoryPluginManager.getPluginFactoryContainer(idString);
					break;

				default :
					throw new IllegalStateException("Unrecognized kind: " + kind + ". Original string: " + kindString); //$NON-NLS-1$ //$NON-NLS-2$
				}

				if (null != container) {
					FactoryPath.Attributes a = new FactoryPath.Attributes( 
							Boolean.parseBoolean(enabledString), Boolean.parseBoolean(runInAptModeString));
					result.put(container, a);
				}
			}
		}

		return result;
	}
	
	/**
	 * Get a file designator for the workspace-level factory path settings file.
	 * Typically this is [workspace]/.metadata/plugins/org.eclipse.jdt.apt.core/.factorypath
	 * @return a java.io.File
	 */
	private static File getFileForWorkspace() {
		return AptPlugin.getPlugin().getStateLocation().append(FACTORYPATH_FILE).toFile();
	}

	/**
	 * Get an Eclipse IFile for the project-level factory path settings file.
	 * Typically this is [project]/.factorypath
	 * @param jproj must not be null
	 * @return an Eclipse IFile
	 */
	private static IFile getIFileForProject(IJavaProject jproj) {
		IProject proj = jproj.getProject();
		return proj.getFile(FACTORYPATH_FILE);
	}

	/**
	 * Does a factory path file already exist for the specified project,
	 * or for the workspace as a whole?
	 * @param jproj if this is null, check for workspace-level settings.
	 * @return true if a settings file exists.
	 */
	public static boolean doesFactoryPathFileExist(IJavaProject jproj) {
		if (jproj == null) {
			File wkspFile = getFileForWorkspace();
			return wkspFile.exists();
		}
		else {
			IFile projFile = getIFileForProject(jproj);
			return projFile.exists();
		}
	}

	/**
	 * Calculates the active factory path for the specified project.  This
	 * depends on the stored information in the .factorypath file, as well as
	 * on the set of plugins that were found at load time of this Eclipse instance.
	 * Returns all containers for the provided project, including disabled ones.
	 * @param jproj The java project in question, or null for the workspace
	 * @return an ordered map, where the key is the container and the value 
	 * indicates whether the container is enabled.
	 */
	private static synchronized Map<FactoryContainer, FactoryPath.Attributes> calculatePath(IJavaProject jproj) {
		Map<FactoryContainer, FactoryPath.Attributes> map = null;
		boolean foundPerProjFile = false;
		if (jproj != null) {
			try {
				map = FactoryPathUtil.readFactoryPathFile(jproj);
				foundPerProjFile = (map != null);
			}
			catch (CoreException ce) {
				AptPlugin.log(ce, "Could not get factory containers for project: " + jproj); //$NON-NLS-1$
			}
		}
		// Workspace if no project data was found
		if (map == null) {
			try {
				map = FactoryPathUtil.readFactoryPathFile(null);
			}
			catch (CoreException ce) {
				AptPlugin.log(ce, "Could not get factory containers for project: " + jproj); //$NON-NLS-1$
			}
		}
		// if no project and no workspace data was found, we'll get the defaults
		if (map == null) {
			map = new LinkedHashMap<FactoryContainer, FactoryPath.Attributes>();
		}
		boolean disableNewPlugins = (jproj != null) && foundPerProjFile;
		updatePluginContainers(map, disableNewPlugins);
		return map;
	}
	
	/**
	 * Removes missing plugin containers, and adds any plugin containers 
	 * that were added since the map was originally created.  The order
	 * of the original list will be maintained, and new entries will be
	 * added to the end of the list in alphabetic order.  The resulting 
	 * list has the same contents as PLUGIN_FACTORY_MAP (that is, all the 
	 * loaded plugins and nothing else), but the order is as close as possible
	 * to the input.
	 * 
	 * @param path the factory path (in raw Map form) to be modified.
	 * @param disableNewPlugins if true, newly discovered plugins will be
	 * disabled.  If false, they will be enabled or disabled according to
	 * their setting in the extension declaration.
	 */
	private static void updatePluginContainers(
			Map<FactoryContainer, FactoryPath.Attributes> path, boolean disableNewPlugins) {
		
		// Get the alphabetically-ordered list of all plugins we found at startup.
		Map<FactoryContainer, FactoryPath.Attributes> pluginContainers = FactoryPluginManager.getAllPluginFactoryContainers();
		
		// Remove from the path any plugins which we did not find at startup
		for (Iterator<FactoryContainer> i = path.keySet().iterator(); i.hasNext(); ) {
			FactoryContainer fc = i.next();
			if (fc.getType() == FactoryContainer.FactoryType.PLUGIN && !pluginContainers.containsKey(fc)) {
				i.remove();
			}
		}
		
		// Add to the end any plugins which are not in the path (i.e., which
		// have been discovered since the config was last saved)
		for (Map.Entry<FactoryContainer, FactoryPath.Attributes> entry : pluginContainers.entrySet()) {
			if (!path.containsKey(entry.getKey())) {
				FactoryPath.Attributes newAttr;
				FactoryPath.Attributes oldAttr = entry.getValue();
				if (disableNewPlugins) {
					newAttr = new FactoryPath.Attributes(false, oldAttr.runInBatchMode());
				} else {
					newAttr = oldAttr;
				}
				path.put(entry.getKey(), newAttr);
			}
		}
	}

	/**
	 * Get a factory path corresponding to the default values: if jproj is
	 * non-null, return the current workspace factory path (workspace prefs
	 * are the default for a project); if jproj is null, return the default 
	 * list of plugin factories (which is the "factory default").
	 */
	public static IFactoryPath getDefaultFactoryPath(IJavaProject jproj) {
		FactoryPath fp = new FactoryPath();
		if (jproj != null) {
			fp.setContainers(calculatePath(null));
		}
		else {
			fp.setContainers(FactoryPluginManager.getAllPluginFactoryContainers());
		}
		return fp;
	}

	public static FactoryPath getFactoryPath(IJavaProject jproj) {
		Map<FactoryContainer, FactoryPath.Attributes> map = calculatePath(jproj);
		FactoryPath fp = new FactoryPath();
		fp.setContainers(map);
		return fp;
	}

	public static void setFactoryPath(IJavaProject jproj, FactoryPath path) 
			throws CoreException {
		Map<FactoryContainer, FactoryPath.Attributes> map = (path != null) ?
				path.getAllContainers() : null;
		saveFactoryPathFile(jproj, map);
	}
	

}
