/*******************************************************************************
 * Copyright (c) 2007, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.update;

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.xml.parsers.*;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.equinox.internal.p2.core.helpers.SecureXMLUtil;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.osgi.util.NLS;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

/**
 * Parser for platform.xml files.
 * 
 * @since 1.0
 */
public class ConfigurationParser implements ConfigurationConstants {
	static final String PLATFORM_BASE = "platform:/base/"; //$NON-NLS-1$
	private URL osgiInstallArea;

	/*
	 * Parse the given file handle which points to a platform.xml file and a
	 * configuration object. Returns null if the file doesn't exist.
	 */
	static Configuration parse(File file, URL osgiInstallArea) throws ProvisionException {
		return new ConfigurationParser(osgiInstallArea).internalParse(file);
	}

	private ConfigurationParser(URL osgiInstallArea) {
		this.osgiInstallArea = osgiInstallArea;
	}

	/*
	 * Create a feature object based on the given DOM node. Return the new feature.
	 */
	private static Feature createFeature(Node node, Site site) {
		Feature result = new Feature(site);
		String id = getAttribute(node, ATTRIBUTE_ID);
		if (id != null)
			result.setId(id);
		String url = getAttribute(node, ATTRIBUTE_URL);
		if (url != null)
			result.setUrl(url);
		String version = getAttribute(node, ATTRIBUTE_VERSION);
		if (version != null)
			result.setVersion(version);
		String pluginIdentifier = getAttribute(node, ATTRIBUTE_PLUGIN_IDENTIFIER);
		if (pluginIdentifier != null)
			result.setPluginIdentifier(pluginIdentifier);
		String pluginVersion = getAttribute(node, ATTRIBUTE_PLUGIN_VERSION);
		// plug-in version is the same as the feature version if it is missing
		if (pluginVersion == null)
			pluginVersion = version;
		if (pluginVersion != null)
			result.setPluginVersion(pluginVersion);
		String application = getAttribute(node, ATTRIBUTE_APPLICATION);
		if (application != null)
			result.setApplication(application);

		// get primary flag
		String flag = getAttribute(node, ATTRIBUTE_PRIMARY);
		if (flag != null && Boolean.parseBoolean(flag))
			result.setPrimary(true);

		// get install locations
		String locations = getAttribute(node, ATTRIBUTE_ROOT);
		if (locations != null) {
			StringTokenizer tokenizer = new StringTokenizer(locations, ","); //$NON-NLS-1$
			ArrayList<URL> rootList = new ArrayList<>();
			while (tokenizer.hasMoreTokens()) {
				try {
					URL rootEntry = new URL(tokenizer.nextToken().trim());
					rootList.add(rootEntry);
				} catch (MalformedURLException e) {
					// skip bad entries ...
				}
			}
			URL[] roots = rootList.toArray(new URL[rootList.size()]);
			result.setRoots(roots);
		}

		return result;
	}

	/*
	 * Create the features from the given DOM node.
	 */
	private static void createFeatures(Node node, Site site) {
		NodeList children = node.getChildNodes();
		int size = children.getLength();
		for (int i = 0; i < size; i++) {
			Node child = children.item(i);
			if (child.getNodeType() != Node.ELEMENT_NODE)
				continue;
			if (!ELEMENT_FEATURE.equalsIgnoreCase(child.getNodeName()))
				continue;
			Feature feature = createFeature(child, site);
			if (feature != null)
				site.addFeature(feature);
		}
	}

	/*
	 * Create a site based on the given DOM node.
	 */
	private Site createSite(Node node) {
		Site result = new Site();
		String policy = getAttribute(node, ATTRIBUTE_POLICY);
		if (policy != null)
			result.setPolicy(policy);
		String enabled = getAttribute(node, ATTRIBUTE_ENABLED);
		if (enabled != null)
			result.setEnabled(Boolean.parseBoolean(enabled));
		String updateable = getAttribute(node, ATTRIBUTE_UPDATEABLE);
		if (updateable != null)
			result.setUpdateable(Boolean.parseBoolean(updateable));
		String url = getAttribute(node, ATTRIBUTE_URL);
		if (url != null) {
			try {
				// do this to ensure the location is an encoded URI
				URI uri = URIUtil.fromString(url);
				URI osgiURI = osgiInstallArea != null ? URIUtil.toURI(osgiInstallArea) : null;
				result.setUrl(getLocation(uri, osgiURI).toString());
			} catch (URISyntaxException e) {
				result.setUrl(url);
			}
		}
		String linkFile = getAttribute(node, ATTRIBUTE_LINKFILE);
		if (linkFile != null)
			result.setLinkFile(linkFile);
		String list = getAttribute(node, ATTRIBUTE_LIST);
		if (list != null)
			for (StringTokenizer tokenizer = new StringTokenizer(list, ","); tokenizer.hasMoreTokens();) //$NON-NLS-1$
				result.addPlugin(tokenizer.nextToken());
		createFeatures(node, result);
		return result;
	}

	/*
	 * Convert the given url string to an absolute url. If the string is
	 * platform:/base/ then return a string which represents the osgi install area.
	 */
	private static URI getLocation(URI location, URI osgiArea) {
		if (osgiArea == null)
			return location;
		if (PLATFORM_BASE.equals(location.toString()))
			return osgiArea;
		return URIUtil.makeAbsolute(location, osgiArea);
	}

	/*
	 * Return the attribute with the given name, or null if it does not exist.
	 */
	private static String getAttribute(Node node, String name) {
		NamedNodeMap attributes = node.getAttributes();
		Node temp = attributes.getNamedItem(name);
		return temp == null ? null : temp.getNodeValue();
	}

	/*
	 * Load the given file into a DOM document.
	 */
	private static Document load(InputStream input) throws ParserConfigurationException, IOException, SAXException {
		// load the feature xml
		DocumentBuilderFactory factory = SecureXMLUtil.newSecureDocumentBuilderFactory();
		DocumentBuilder builder = factory.newDocumentBuilder();
		input = new BufferedInputStream(input);
		try {
			return builder.parse(input);
		} finally {
			if (input != null)
				try {
					input.close();
				} catch (IOException e) {
					// ignore
				}
		}
	}

	/*
	 * Parse the given file handle which points to a platform.xml file and a
	 * configuration object. Returns null if the file doesn't exist.
	 */
	private Configuration internalParse(File file) throws ProvisionException {
		if (!file.exists()) {
			// remove from cache since it doesn't exist anymore on disk
			ConfigurationCache.put(file, null);
			return null;
		}
		// have we read this before?
		Configuration result = ConfigurationCache.get(file);
		if (result != null)
			return result;
		try {
			InputStream input = new BufferedInputStream(new FileInputStream(file));
			Document document = load(input);
			result = process(document);
			// save for future use
			ConfigurationCache.put(file, result);
			return result;
		} catch (IOException e) {
			throw new ProvisionException(NLS.bind(Messages.error_reading_config, file), e);
		} catch (ParserConfigurationException e) {
			throw new ProvisionException(Messages.error_parsing_config, e);
		} catch (SAXException e) {
			throw new ProvisionException(Messages.error_parsing_config, e);
		}
	}

	/*
	 * Process the given DOM document and create the appropriate site objects.
	 */
	private Configuration process(Document document) {
		Node node = getConfigElement(document);
		if (node == null)
			return null;
		Configuration configuration = createConfiguration(node);
		NodeList children = node.getChildNodes();
		int size = children.getLength();
		for (int i = 0; i < size; i++) {
			Node child = children.item(i);
			if (child.getNodeType() != Node.ELEMENT_NODE)
				continue;
			if (!ELEMENT_SITE.equalsIgnoreCase(child.getNodeName()))
				continue;
			Site site = createSite(child);
			if (site != null)
				configuration.add(site);
		}
		return configuration;
	}

	private static Configuration createConfiguration(Node node) {
		Configuration result = new Configuration();
		String value = getAttribute(node, ATTRIBUTE_DATE);
		if (value != null)
			result.setDate(value);
		value = getAttribute(node, ATTRIBUTE_TRANSIENT);
		if (value != null)
			result.setTransient(Boolean.parseBoolean(value));
		value = getAttribute(node, ATTRIBUTE_SHARED_UR);
		if (value != null)
			result.setSharedUR(value);
		value = getAttribute(node, ATTRIBUTE_VERSION);
		if (value != null)
			result.setVersion(value);
		return result;
	}

	private static Node getConfigElement(Document doc) {
		NodeList children = doc.getChildNodes();
		int size = children.getLength();
		for (int i = 0; i < size; i++) {
			Node child = children.item(i);
			if (child.getNodeType() != Node.ELEMENT_NODE)
				continue;
			if (ELEMENT_CONFIG.equalsIgnoreCase(child.getNodeName()))
				return child;
		}
		return null;
	}
}
