/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Cloudsmith Inc - split into FeatureParser and FeatureManifestParser
 *     SAP AG - consolidation of publishers for PDE formats
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.publisher.eclipse;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.SecureXMLUtil;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.publisher.eclipse.Feature;
import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.internal.publishing.Activator;
import org.eclipse.pde.internal.publishing.Constants;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Parses a feature manifest from a provided stream.
 */
public class FeatureManifestParser extends DefaultHandler {

	private final static SAXParserFactory parserFactory = SecureXMLUtil.newSecureSAXParserFactory();
	private SAXParser parser;
	protected Feature result;
	private URL url;
	private StringBuffer characters = null;
	private MultiStatus status = null;
	private boolean hasImports = false;

	private final List<String> messageKeys = new ArrayList<String>();

	public FeatureManifestParser() {
		this(true);
	}

	public FeatureManifestParser(boolean createParser) {
		super();
		if (!createParser)
			return;
		try {
			parserFactory.setNamespaceAware(true);
			this.parser = parserFactory.newSAXParser();
		} catch (ParserConfigurationException e) {
			System.out.println(e);
		} catch (SAXException e) {
			System.out.println(e);
		}
	}

	@Override
	public void characters(char[] ch, int start, int length) {
		if (characters == null)
			return;
		characters.append(ch, start, length);
	}

	protected Feature createFeature(String id, String version) {
		return new Feature(id, version);
	}

	@Override
	public void endElement(String uri, String localName, String qName) {
		if ("requires".equals(localName) && !hasImports) { //$NON-NLS-1$
			error(Messages.feature_parse_emptyRequires);
		}
		if (characters == null)
			return;
		if ("description".equals(localName)) { //$NON-NLS-1$
			result.setDescription(localize(characters.toString().trim()));
		} else if ("license".equals(localName)) { //$NON-NLS-1$
			result.setLicense(localize(characters.toString().trim()));
		} else if ("copyright".equals(localName)) { //$NON-NLS-1$
			result.setCopyright(localize(characters.toString().trim()));
		}
		characters = null;
	}

	private void error(String message) {
		if (status == null) {
			String msg = NLS.bind(Messages.exception_featureParse, url.toExternalForm());
			status = new MultiStatus(Activator.ID, Constants.EXCEPTION_FEATURE_PARSE, msg, null);
		}
		status.add(new Status(IStatus.ERROR, Activator.ID, Constants.EXCEPTION_FEATURE_PARSE, message, null));
	}

	public MultiStatus getStatus() {
		return status;
	}

	public List<String> getMessageKeys() {
		return messageKeys;
	}

	public Feature getResult() {
		return result;
	}

	private String localize(String value) {
		if (value != null && value.startsWith("%")) { //$NON-NLS-1$
			String key = value.substring(1);
			messageKeys.add(key);
		}
		return value;
	}

	/**
	 * Parse the given input stream and return a feature object
	 * or null.
	 */
	public Feature parse(InputStream in, URL featureURL) throws SAXException, IOException {
		result = null;
		url = featureURL;
		parser.parse(new InputSource(in), this);
		return result;
	}

	private void processCopyright(Attributes attributes) {
		result.setCopyrightURL(attributes.getValue("url")); //$NON-NLS-1$
		characters = new StringBuffer();
	}

	private void processDescription(Attributes attributes) {
		result.setDescriptionURL(attributes.getValue("url")); //$NON-NLS-1$
		characters = new StringBuffer();
	}

	private void processDiscoverySite(Attributes attributes) {
		//ignore discovery sites of type 'web'
		if ("web".equals(attributes.getValue("type"))) //$NON-NLS-1$ //$NON-NLS-2$
			return;
		result.addDiscoverySite(attributes.getValue("label"), attributes.getValue("url")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	protected void processFeature(Attributes attributes) {
		String id = attributes.getValue("id"); //$NON-NLS-1$
		String ver = attributes.getValue("version"); //$NON-NLS-1$

		if (id == null || id.trim().equals("") //$NON-NLS-1$
				|| ver == null || ver.trim().equals("")) { //$NON-NLS-1$
			error(NLS.bind(Messages.feature_parse_invalidIdOrVersion, (new String[] {id, ver})));
		} else {
			result = createFeature(id, ver);

			String os = attributes.getValue("os"); //$NON-NLS-1$
			String ws = attributes.getValue("ws"); //$NON-NLS-1$
			String nl = attributes.getValue("nl"); //$NON-NLS-1$
			String arch = attributes.getValue("arch"); //$NON-NLS-1$
			result.setEnvironment(os, ws, arch, nl);

			result.setApplication(attributes.getValue("application")); //$NON-NLS-1$
			result.setBrandingPlugin(attributes.getValue("plugin")); //$NON-NLS-1$
			result.setExclusive(Boolean.parseBoolean(attributes.getValue("exclusive"))); //$NON-NLS-1$
			result.setPrimary(Boolean.parseBoolean(attributes.getValue("primary"))); //$NON-NLS-1$
			result.setColocationAffinity(attributes.getValue("colocation-affinity")); //$NON-NLS-1$

			result.setProviderName(localize(attributes.getValue("provider-name"))); //$NON-NLS-1$
			result.setLabel(localize(attributes.getValue("label"))); //$NON-NLS-1$
			result.setImage(attributes.getValue("image")); //$NON-NLS-1$
			result.setLicenseFeature(attributes.getValue("license-feature")); //$NON-NLS-1$
			result.setLicenseFeatureVersion(attributes.getValue("license-feature-version")); //$NON-NLS-1$

			//			Utils.debug("End process DefaultFeature tag: id:" +id + " ver:" +ver + " url:" + feature.getURL()); 	 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
	}

	private void processImport(Attributes attributes) {
		String id = attributes.getValue("feature"); //$NON-NLS-1$
		boolean isPlugin = false;
		if (id == null) {
			id = attributes.getValue("plugin"); //$NON-NLS-1$
			if (id == null)
				throw new IllegalStateException();
			isPlugin = true;
		}
		String versionStr = attributes.getValue("version"); //$NON-NLS-1$
		FeatureEntry entry = null;
		if ("versionRange".equals(attributes.getValue("match"))) { //$NON-NLS-1$//$NON-NLS-2$
			VersionRange versionRange = new VersionRange(versionStr);
			entry = FeatureEntry.createRequires(id, versionRange, attributes.getValue("match"), attributes.getValue("filter"), isPlugin); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			entry = FeatureEntry.createRequires(id, versionStr, attributes.getValue("match"), attributes.getValue("filter"), isPlugin); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (!isPlugin && "true".equalsIgnoreCase(attributes.getValue("patch"))) { //$NON-NLS-1$ //$NON-NLS-2$
			entry.setPatch(true);
		}
		hasImports = true;
		result.addEntry(entry);
	}

	private void processIncludes(Attributes attributes) {
		FeatureEntry entry = new FeatureEntry(attributes.getValue("id"), attributes.getValue("version"), false); //$NON-NLS-1$ //$NON-NLS-2$
		String unpack = attributes.getValue("unpack"); //$NON-NLS-1$
		if (unpack != null)
			entry.setUnpack(Boolean.parseBoolean(unpack));
		String optional = attributes.getValue("optional"); //$NON-NLS-1$
		if (optional != null)
			entry.setOptional(Boolean.parseBoolean(optional));
		setEnvironment(attributes, entry);
		String filter = attributes.getValue("filter"); //$NON-NLS-1$
		if (filter != null)
			entry.setFilter(filter);
		result.addEntry(entry);
	}

	private void processInstallHandler(Attributes attributes) {
		result.setInstallHandler(attributes.getValue("handler")); //$NON-NLS-1$
		result.setInstallHandlerLibrary(attributes.getValue("library")); //$NON-NLS-1$
		result.setInstallHandlerURL(attributes.getValue("url")); //$NON-NLS-1$
	}

	private void processLicense(Attributes attributes) {
		result.setLicenseURL(attributes.getValue("url")); //$NON-NLS-1$
		characters = new StringBuffer();
	}

	private void processPlugin(Attributes attributes) {
		String id = attributes.getValue("id"); //$NON-NLS-1$
		String version = attributes.getValue("version"); //$NON-NLS-1$

		if (id == null || id.trim().equals("") || version == null || version.trim().equals("")) { //$NON-NLS-1$ //$NON-NLS-2$
			error(NLS.bind(Messages.feature_parse_invalidIdOrVersion, (new String[] {id, version})));
		} else {
			FeatureEntry plugin = new FeatureEntry(id, version, true);
			setEnvironment(attributes, plugin);
			String unpack = attributes.getValue("unpack"); //$NON-NLS-1$
			if (unpack != null)
				plugin.setUnpack(Boolean.parseBoolean(unpack));
			String fragment = attributes.getValue("fragment"); //$NON-NLS-1$
			if (fragment != null)
				plugin.setFragment(Boolean.parseBoolean(fragment));
			String filter = attributes.getValue("filter"); //$NON-NLS-1$
			if (filter != null)
				plugin.setFilter(filter);
			result.addEntry(plugin);

			//			Utils.debug("End process DefaultFeature tag: id:" + id + " ver:" + ver + " url:" + feature.getURL()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
	}

	private void processUpdateSite(Attributes attributes) {
		result.setUpdateSiteLabel(attributes.getValue("label")); //$NON-NLS-1$
		result.setUpdateSiteURL(attributes.getValue("url")); //$NON-NLS-1$
	}

	private void setEnvironment(Attributes attributes, FeatureEntry entry) {
		String os = attributes.getValue("os"); //$NON-NLS-1$
		String ws = attributes.getValue("ws"); //$NON-NLS-1$
		String nl = attributes.getValue("nl"); //$NON-NLS-1$
		String arch = attributes.getValue("arch"); //$NON-NLS-1$
		entry.setEnvironment(os, ws, arch, nl);
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) {
		//		Utils.debug("Start Element: uri:" + uri + " local Name:" + localName + " qName:" + qName); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		if ("plugin".equals(localName)) { //$NON-NLS-1$
			processPlugin(attributes);
		} else if ("description".equals(localName)) { //$NON-NLS-1$
			processDescription(attributes);
		} else if ("license".equals(localName)) { //$NON-NLS-1$
			processLicense(attributes);
		} else if ("copyright".equals(localName)) { //$NON-NLS-1$
			processCopyright(attributes);
		} else if ("feature".equals(localName)) { //$NON-NLS-1$
			processFeature(attributes);
		} else if ("import".equals(localName)) { //$NON-NLS-1$
			processImport(attributes);
		} else if ("includes".equals(localName)) { //$NON-NLS-1$
			processIncludes(attributes);
		} else if ("install-handler".equals(localName)) { //$NON-NLS-1$
			processInstallHandler(attributes);
		} else if ("update".equals(localName)) { //$NON-NLS-1$
			processUpdateSite(attributes);
		} else if ("discovery".equals(localName)) { //$NON-NLS-1$
			processDiscoverySite(attributes);
		}
	}

}
