/*******************************************************************************
 * Copyright (c) 2000, 2007 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
 *     James D Miles (IBM Corp.) - bug 191368, Policy URL doesn't support UTF-8 characters
 *******************************************************************************/
package org.eclipse.update.internal.search;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

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

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.core.ISite;
import org.eclipse.update.core.Utilities;
import org.eclipse.update.internal.core.Messages;
import org.eclipse.update.internal.core.URLEncoder;
import org.eclipse.update.internal.core.UpdateManagerUtils;
import org.eclipse.update.internal.core.connection.ConnectionFactory;
import org.eclipse.update.internal.core.connection.IResponse;
import org.eclipse.update.search.IUpdateSiteAdapter;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * 
 * This class opens connection to the update map resource
 * and parses the file to load update URL mappings.
 * These mappings are used to redirect new updates search
 * when the redirection pattern matches.
 */

public class UpdatePolicy {
	private static final String TAG_POLICY = "update-policy"; //$NON-NLS-1$
	private static final String TAG_URL_MAP = "url-map"; //$NON-NLS-1$
	private static final String ATT_URL = "url"; //$NON-NLS-1$
	private static final String ATT_PATTERN = "pattern"; //$NON-NLS-1$
	private static final String ATT_TYPE = "url-type"; //$NON-NLS-1$
	private static final String ATT_TYPE_VALUE_UPDATE = "update"; //$NON-NLS-1$
	//private static final String ATT_TYPE_VALUE_BOTH = "both"; //$NON-NLS-1$
	private static final String ATT_TYPE_VALUE_DISCOVERY = "discovery"; //$NON-NLS-1$

	private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

	private static class MapSite implements IUpdateSiteAdapter {
		private URL url;
		public MapSite(URL url) {
			this.url = url;
		}
		public String getLabel() {
			if (url == null) {
				return ""; //$NON-NLS-1$
			}
			return url.toString();
		}
		public URL getURL() {
			return url;
		}
	}

	private static class UpdateMapEntry {
		private IUpdateSiteAdapter site;
		private String pattern;

		public UpdateMapEntry(String pattern, URL url) {
			this.pattern = pattern;
			this.site = new MapSite(url);
		}
		public IUpdateSiteAdapter getSite() {
			return site;
		}
		public boolean matches(String id) {
			return id.startsWith(pattern);
		}
		public String getPattern() {
			return pattern;
		}
	}

	private ArrayList entries;
	private ArrayList discoveryEntries;
	private IUpdateSiteAdapter defaultSite;
	private IUpdateSiteAdapter defaultDiscoverySite;
	private boolean loaded = false;
	private boolean fallbackAllowed = true;

	public UpdatePolicy() {
		entries = new ArrayList();
		discoveryEntries = new ArrayList();
	}

	public void load(URL mapFile, IProgressMonitor monitor)
		throws CoreException {
		InputStream policyStream = null;
		try {
			IResponse response = ConnectionFactory.get(mapFile);
			UpdateManagerUtils.checkConnectionResult(response, mapFile);
			policyStream = response.getInputStream(monitor);
			// the stream can be null if the user cancels the connection
			if (policyStream == null)
				return;
			
			documentBuilderFactory.setNamespaceAware(true);
			DocumentBuilder parser = documentBuilderFactory.newDocumentBuilder();
			Document doc = parser.parse(new InputSource(policyStream));

			processUpdatePolicy(doc);
			loaded = true;
		} catch (IOException e) {
			throw Utilities.newCoreException(
				NLS.bind(Messages.SiteURLFactory_UnableToAccessSiteStream, (new String[] { mapFile == null ? "" : mapFile.toExternalForm() })), //$NON-NLS-1$
				ISite.SITE_ACCESS_EXCEPTION,
				e);
		} catch (SAXException e) {
			throw Utilities.newCoreException(
				Messages.UpdatePolicy_parsePolicy, 
				0,
				e);

		} catch(ParserConfigurationException e) {
			throw Utilities.newCoreException(
				Messages.UpdatePolicy_parsePolicy, 
				0,
				e);
		} finally {
			if (policyStream != null) {
				try {
					policyStream.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public boolean isLoaded() {
		return loaded;
	}
	
	/*
	 * Given the feature ID, returns the mapped update URL if
	 * found in the mappings. This URL will be used INSTEAD of
	 * the update URL encoded in the feature itself during the
	 * new update search.
	 * <p>In case of multiple matches (e.g. org.eclipse and org.eclipse.platform)
	 * the URL for the longer pattern will be picked (i.e. org.eclipse.platform).
	 */
	public IUpdateSiteAdapter getMappedSite(String id) {
		UpdateMapEntry lastEntry = null;
		for (int i = 0; i < entries.size(); i++) {
			UpdateMapEntry entry = (UpdateMapEntry) entries.get(i);
			if (entry.matches(id)) {
				if (lastEntry == null)
					lastEntry = entry;
				else {
					// Choose the match with longer pattern.
					// For example, if two matches are found:
					// 'org.eclipse' and 'org.eclipse.platform',
					// pick 'org.eclipse.platform'.
					String pattern = entry.getPattern();
					String lastPattern = lastEntry.getPattern();
					if (pattern.length() > lastPattern.length())
						lastEntry = entry;
				}
			}
		}
		if (lastEntry != null)
			return lastEntry.getSite();
		else
			return defaultSite;
	}
	
	/*
	 * Given the feature ID, returns the mapped discovery URL if
	 * found in the mappings. This URL will be used INSTEAD of
	 * the discovery URL encoded in the feature itself during the
	 * new search.
	 * <p>In case of multiple matches (e.g. org.eclipse and org.eclipse.platform)
	 * the URL for the longer pattern will be picked (i.e. org.eclipse.platform).
	 */
	public IUpdateSiteAdapter getMappedDiscoverySite(String id) {
		UpdateMapEntry lastEntry = null;
		for (int i = 0; i < discoveryEntries.size(); i++) {
			UpdateMapEntry entry = (UpdateMapEntry) discoveryEntries.get(i);
			if (entry.matches(id)) {
				if (lastEntry == null)
					lastEntry = entry;
				else {
					// Choose the match with longer pattern.
					// For example, if two matches are found:
					// 'org.eclipse' and 'org.eclipse.platform',
					// pick 'org.eclipse.platform'.
					String pattern = entry.getPattern();
					String lastPattern = lastEntry.getPattern();
					if (pattern.length() > lastPattern.length())
						lastEntry = entry;
				}
			}
		}
		if (lastEntry != null)
			return lastEntry.getSite();
		else
			return defaultDiscoverySite;
	}

	public boolean isFallbackAllowed() {
		return fallbackAllowed;
	}
	
	private void reset() {
		if (!entries.isEmpty())
			entries.clear();
		if (!discoveryEntries.isEmpty())
			discoveryEntries.clear();
	}

	private void processUpdatePolicy(Document document) throws CoreException {
		Node root = document.getDocumentElement();
		reset();
		
		if (root.getNodeName().equals(TAG_POLICY)==false)
			throwCoreException("'"+TAG_POLICY+Messages.UpdatePolicy_policyExpected, null);  //$NON-NLS-1$
				
		NodeList nodes = root.getChildNodes();
		
		for (int i=0; i<nodes.getLength(); i++) {
			Node child = nodes.item(i);
			if (child.getNodeType() != Node.ELEMENT_NODE)
				continue;
			String tag = child.getNodeName();
			if (tag.equals(TAG_URL_MAP))
				processMapNode(child);
		}
	}
	private void processMapNode(Node node) throws CoreException {
		String pattern = getAttribute(node, ATT_PATTERN);
		String urlName = getAttribute(node, ATT_URL);
		String type = getAttribute(node, ATT_TYPE);
		
		assertNotNull(ATT_PATTERN, pattern);
		assertNotNull(ATT_URL, urlName);
		
		// empty url means feature is not updateable
		if (urlName.trim().length() == 0) {
			addUpdateEntry(pattern, null, type);
			return;
		}

		try {
			URL url = new URL(urlName);
			URL resolvedURL = URLEncoder.encode(url);
			addUpdateEntry(pattern, resolvedURL, type);
		} catch (MalformedURLException e) {
			throwCoreException(Messages.UpdatePolicy_invalidURL+urlName, null); 
		} 
	}
	
	private void assertNotNull(String name, String value) throws CoreException {
		if (value==null)
			throwCoreException(name+Messages.UpdatePolicy_nameNoNull, null); 
	}
	
	private String getAttribute(Node node, String name) {
		NamedNodeMap attMap = node.getAttributes();
		Node att = attMap.getNamedItem(name);
		if (att==null) return null;
		return att.getNodeValue();
	}

	private void addUpdateEntry(String pattern, URL url, String type) {
		if (pattern.equalsIgnoreCase("*")) {//$NON-NLS-1$
			if (type == null)
				defaultSite = new MapSite(url);
			else if (type.equals(ATT_TYPE_VALUE_UPDATE))
				defaultSite = new MapSite(url);
			else if (type.equals(ATT_TYPE_VALUE_DISCOVERY))
				defaultDiscoverySite = new MapSite(url);
			else {
				defaultSite = new MapSite(url);
				defaultDiscoverySite = new MapSite(url);
			}
		} else {
			if (type == null )
				entries.add(new UpdateMapEntry(pattern, url));
			else if (type.equals(ATT_TYPE_VALUE_UPDATE))
				entries.add(new UpdateMapEntry(pattern, url));
			else if (type.equals(ATT_TYPE_VALUE_DISCOVERY))
				discoveryEntries.add(new UpdateMapEntry(pattern, url));
			else {
				entries.add(new UpdateMapEntry(pattern, url));
				discoveryEntries.add(new UpdateMapEntry(pattern, url));
			}
		}
	}
	
	private void throwCoreException(String message, Throwable e) throws CoreException {
		String fullMessage = Messages.UpdatePolicy_UpdatePolicy+message; 
		throw Utilities.newCoreException(fullMessage, 0, e);
	}
}
