/*******************************************************************************
 * Copyright (c) 2005, 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
 *     G&H Softwareentwicklung GmbH - internationalization implementation (bug 150933)
 *     Michael Seele -  remove offline-allowed  (bug 153403)
 ******************************************************************************/

package org.eclipse.pde.internal.build.tasks;

import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @since 3.1
 */
public class JNLPGenerator extends DefaultHandler {

	private SAXParser parser;
	private final File featureRoot;

	private final String codebase;
	private final String j2se;

	/**
	 * id = ???
	 * version = jnlp.version
	 * label = information.title
	 * provider-name = information.vendor
	 * image = information.icon
	 * feature.description = information.description
	 * feature.includes = extension
	 * feature.plugin = jar
	 */
	private final static SAXParserFactory parserFactory = SAXParserFactory.newInstance();
	private PrintWriter out;
	private String destination;
	private String provider;
	private String label;
	private String version;
	private String id;
	private String description;
	private boolean resourceWritten = false;
	private String currentOS = null;
	private String currentArch = null;
	private Locale locale = null;
	private PropertyResourceBundle nlsBundle = null;
	private final boolean generateOfflineAllowed;
	private Config[] configs;

	/**
	 * For testing purposes only.
	 */
	public static void main(String[] args) {
		JNLPGenerator generator = new JNLPGenerator(args[0], args[1], args[2], args[3]);
		generator.process();
	}

	/**
	 * Constructs a feature parser.
	 */
	public JNLPGenerator(String feature, String destination, String codebase, String j2se) {
		this(feature, destination, codebase, j2se, Locale.getDefault(), true, null);
	}

	/**
	 * Constructs a feature parser.
	 */
	public JNLPGenerator(String feature, String destination, String codebase, String j2se, Locale locale, boolean generateOfflineAllowed, String configs) {
		super();
		this.featureRoot = new File(feature);
		this.destination = destination;
		this.codebase = codebase;
		this.j2se = j2se;
		this.locale = locale;
		this.generateOfflineAllowed = generateOfflineAllowed;
		try {
			parserFactory.setNamespaceAware(true);
			parser = parserFactory.newSAXParser();
		} catch (ParserConfigurationException e) {
			System.out.println(e);
		} catch (SAXException e) {
			System.out.println(e);
		}
		setConfigInfo(configs);
	}

	/**
	 * Parses the specified url and constructs a feature
	 */
	public void process() {
		InputStream in = null;
		final String FEATURE_XML = "feature.xml"; //$NON-NLS-1$

		try {
			ZipFile featureArchive = null;
			InputStream nlsStream = null;
			if (featureRoot.isFile()) {
				featureArchive = new ZipFile(featureRoot);
				nlsStream = getNLSStream(featureArchive);
				ZipEntry featureXML = featureArchive.getEntry(FEATURE_XML);
				in = featureArchive.getInputStream(featureXML);
			} else {
				nlsStream = getNLSStream(this.featureRoot);
				in = new BufferedInputStream(new FileInputStream(new File(featureRoot, FEATURE_XML)));
			}
			try {
				if (nlsStream != null) {
					nlsBundle = new PropertyResourceBundle(nlsStream);
					nlsStream.close();
				}
			} catch (IOException e) {
				// do nothing
			}
			try {
				parser.parse(new InputSource(in), this);
				writeResourceEpilogue();
				writeEpilogue();
			} catch (SAXException e) {
				//Ignore the exception
			} finally {
				in.close();
				if (out != null)
					out.close();
				if (featureArchive != null)
					featureArchive.close();
			}
		} catch (IOException e) {
			//Ignore the exception
		}
	}

	/**
	 * Search for nls properties files and return the stream if files are found.
	 * First try to load the default properties file, then one with the default
	 * locale settings and if nothing matches, return the stream of the first
	 * properties file found.
	 */
	private InputStream getNLSStream(File root) {
		String appendix = ".properties"; //$NON-NLS-1$
		String[] potentials = createNLSPotentials();

		Map validEntries = new HashMap();
		File[] files = root.listFiles();
		for (int i = 0; i < files.length; i++) {
			String filename = files[i].getName();
			if (filename.endsWith(appendix)) {
				validEntries.put(filename, files[i]);
			}
		}
		InputStream stream = null;
		if (validEntries.size() > 0) {
			for (int i = 0; i < potentials.length; i++) {
				File file = (File) validEntries.get(potentials[i]);
				if (file != null) {
					try {
						stream = new BufferedInputStream(new FileInputStream(file));
						break;
					} catch (IOException e) {
						// do nothing
					}
				}
			}
			if (stream == null) {
				File file = (File) validEntries.values().iterator().next();
				try {
					stream = new BufferedInputStream(new FileInputStream(file));
				} catch (IOException e) {
					// do nothing
				}
			}
		}
		return stream;
	}

	/**
	 * Search for nls properties files and return the stream if files are found.
	 * First try to load the default properties file, then one with the default
	 * locale settings and if nothing matches, return the stream of the first
	 * founded properties file.
	 */
	private InputStream getNLSStream(ZipFile featureArchive) {
		String appendix = ".properties"; //$NON-NLS-1$
		String[] potentials = createNLSPotentials();

		Map validEntries = new HashMap();
		for (Enumeration enumeration = featureArchive.entries(); enumeration.hasMoreElements();) {
			ZipEntry entry = (ZipEntry) enumeration.nextElement();
			String entryName = entry.getName();
			if (entryName.endsWith(appendix)) {
				validEntries.put(entryName, entry);
			}
		}
		InputStream stream = null;
		if (validEntries.size() > 0) {
			for (int i = 0; i < potentials.length; i++) {
				ZipEntry entry = (ZipEntry) validEntries.get(potentials[i]);
				if (entry != null) {
					try {
						stream = featureArchive.getInputStream(entry);
						break;
					} catch (IOException e) {
						// do nothing
					}
				}
			}
			if (stream == null) {
				ZipEntry entry = (ZipEntry) validEntries.values().iterator().next();
				try {
					stream = featureArchive.getInputStream(entry);
				} catch (IOException e) {
					// do nothing
				}
			}
		}
		return stream;
	}

	private String[] createNLSPotentials() {
		String suffix = "feature"; //$NON-NLS-1$
		String appendix = ".properties"; //$NON-NLS-1$

		String language = locale.getLanguage();
		String country = locale.getCountry();
		String variant = locale.getVariant();

		String potential1 = '_' + language + '_' + country + '_' + variant;
		String potential2 = '_' + language + '_' + country;
		String potential3 = '_' + language;
		String potential4 = ""; //$NON-NLS-1$

		String[] potentials = new String[] {potential1, potential2, potential3, potential4};
		for (int i = 0; i < potentials.length; i++) {
			potentials[i] = suffix + potentials[i] + appendix;
		}
		return potentials;
	}

	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		try {
			if ("feature".equals(localName)) { //$NON-NLS-1$
				processFeature(attributes);
			} else if ("includes".equals(localName)) { //$NON-NLS-1$
				processIncludes(attributes);
			} else if ("description".equals(localName)) { //$NON-NLS-1$
				processDescription(attributes);
			} else if ("plugin".equals(localName)) { //$NON-NLS-1$
				processPlugin(attributes);
			}
		} catch (IOException e) {
			throw new SAXException(e);
		}
	}

	private void processPlugin(Attributes attributes) throws IOException {
		writePrologue();
		String pluginId = attributes.getValue("id"); //$NON-NLS-1$
		String pluginVersion = attributes.getValue("version"); //$NON-NLS-1$
		String os = attributes.getValue("os"); //$NON-NLS-1$
		String ws = attributes.getValue("ws"); //$NON-NLS-1$
		String arch = attributes.getValue("arch"); //$NON-NLS-1$
		if (isValidEnvironment(os, ws, arch)) {
			writeResourcePrologue(os, ws, arch);
			out.println("\t\t<jar href=\"plugins/" + pluginId + "_" + pluginVersion + ".jar\"/>"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
		}
	}

	private void writeResourceEpilogue() {
		if (!resourceWritten)
			return;
		out.println("\t</resources>"); //$NON-NLS-1$
		resourceWritten = false;
		currentOS = null;
	}

	private void writeResourcePrologue(String os, String ws, String arch) {
		if (os == null)
			os = ws;
		os = convertOS(os);
		arch = convertArch(arch);
		if (resourceWritten && osMatch(os) && archMatch(arch))
			return;
		if (resourceWritten)
			writeResourceEpilogue();
		out.println("\t<resources" + (os == null ? "" : " os=\"" + os + "\"") + (arch == null ? "" : " arch=\"" + arch + "\"") + ">"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$//$NON-NLS-7$ //$NON-NLS-8$
		resourceWritten = true;
		currentOS = os;
		currentArch = arch;
	}

	private String convertOS(String os) {
		if (os == null)
			return null;
		if ("win32".equalsIgnoreCase(os)) //$NON-NLS-1$
			return "Windows"; //$NON-NLS-1$
		if ("macosx".equalsIgnoreCase(os)) //$NON-NLS-1$
			return "Mac"; //$NON-NLS-1$
		if ("linux".equalsIgnoreCase(os)) //$NON-NLS-1$
			return "Linux"; //$NON-NLS-1$
		if ("solaris".equalsIgnoreCase(os)) //$NON-NLS-1$
			return "Solaris"; //$NON-NLS-1$
		if ("hpux".equalsIgnoreCase(os)) //$NON-NLS-1$
			return "HP-UX"; //$NON-NLS-1$
		if ("aix".equalsIgnoreCase(os)) //$NON-NLS-1$
			return "AIX"; //$NON-NLS-1$
		return os;
	}

	private boolean osMatch(String os) {
		if (os == currentOS)
			return true;
		if (os == null)
			return false;
		return os.equals(currentOS);
	}

	private String convertArch(String arch) {
		if (arch == null)
			return null;

		if ("x86".equals(arch)) //$NON-NLS-1$
			return "x86"; //$NON-NLS-1$

		if ("PA_RISC".equals(arch)) //$NON-NLS-1$
			return "PA_RISC"; //$NON-NLS-1$

		if ("ppc".equals(arch)) //$NON-NLS-1$
			return "ppc"; //$NON-NLS-1$

		if ("sparc".equals(arch)) //$NON-NLS-1$
			return "sparc"; //$NON-NLS-1$

		if ("x86_64".equals(arch))//$NON-NLS-1$
			return "x86_64"; //$NON-NLS-1$

		if ("ia64".equals(arch)) //$NON-NLS-1$
			return "ia64"; //$NON-NLS-1$

		if ("ia64_32".equals(arch)) //$NON-NLS-1$
			return "ia64_32"; //$NON-NLS-1$

		return arch;
	}

	private boolean archMatch(String arch) {
		if (arch == currentOS)
			return true;
		if (arch == null)
			return false;
		return arch.equals(currentArch);
	}

	private void processDescription(Attributes attributes) {
		// ignoring for now
	}

	private void processIncludes(Attributes attributes) throws IOException {
		writePrologue();
		String inclusionId = attributes.getValue("id"); //$NON-NLS-1$
		String inclusionVersion = attributes.getValue("version"); //$NON-NLS-1$
		String name = attributes.getValue("name"); //$NON-NLS-1$
		String os = attributes.getValue("os"); //$NON-NLS-1$
		String ws = attributes.getValue("ws"); //$NON-NLS-1$
		String arch = attributes.getValue("arch"); //$NON-NLS-1$
		if (isValidEnvironment(os, ws, arch)) {
			writeResourcePrologue(os, ws, arch);
			out.print("\t\t<extension ");//$NON-NLS-1$
			if (name != null)
				out.print("name=\"" + name + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
			if (inclusionId != null) {
				out.print("href=\"features/" + inclusionId); //$NON-NLS-1$
				if (inclusionVersion != null)
					out.print('_' + inclusionVersion);
				out.print(".jnlp\" "); //$NON-NLS-1$
			}
			out.println("/>"); //$NON-NLS-1$
		}
	}

	private void processFeature(Attributes attributes) {
		id = attributes.getValue("id"); //$NON-NLS-1$
		version = attributes.getValue("version"); //$NON-NLS-1$
		label = processNLS(attributes.getValue("label")); //$NON-NLS-1$
		provider = processNLS(attributes.getValue("provider-name")); //$NON-NLS-1$
	}

	/**
	 * Search for a human readable string in the feature.properties file(s) if
	 * the given string is a translateable key.
	 *
	 * @param string a translateable key or a normal string(nothing is done)
	 *
	 * @return a translateabled string or the given string if it is not a
	 *         translateable key
	 */
	private String processNLS(String string) {
		if (string == null)
			return null;
		string = string.trim();
		if (!string.startsWith("%")) { //$NON-NLS-1$
			return string;
		}
		if (string.startsWith("%%")) { //$NON-NLS-1$
			return string.substring(1);
		}
		int index = string.indexOf(" "); //$NON-NLS-1$
		String key = index == -1 ? string : string.substring(0, index);
		String dflt = index == -1 ? string : string.substring(index + 1);
		if (nlsBundle == null) {
			return dflt;
		}
		try {
			return nlsBundle.getString(key.substring(1));
		} catch (MissingResourceException e) {
			return dflt;
		}
	}

	private void writePrologue() throws IOException {
		if (out != null)
			return;
		if (destination == null) {
			featureRoot.getParentFile();
			destination = featureRoot.getParent() + '/';
		}
		if (destination.endsWith("/") || destination.endsWith("\\")) //$NON-NLS-1$  //$NON-NLS-2$
			destination = new File(featureRoot.getParentFile(), id + "_" + version + ".jnlp").getAbsolutePath(); //$NON-NLS-1$ //$NON-NLS-2$
		out = new PrintWriter(new BufferedOutputStream(new FileOutputStream(destination)));
		writePrologue();
		out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
		out.print("<jnlp spec=\"1.0+\" "); //$NON-NLS-1$
		if (codebase != null)
			out.print("codebase=\"" + codebase); //$NON-NLS-1$
		out.println("\">"); //$NON-NLS-1$
		out.println("\t<information>"); //$NON-NLS-1$
		if (label != null)
			out.println("\t\t<title>" + label + "</title>"); //$NON-NLS-1$ //$NON-NLS-2$
		if (provider != null)
			out.println("\t\t<vendor>" + provider + "</vendor>"); //$NON-NLS-1$ //$NON-NLS-2$
		if (description != null)
			out.println("\t\t<description>" + description + "</description>"); //$NON-NLS-1$ //$NON-NLS-2$
		if (generateOfflineAllowed)
			out.println("\t\t<offline-allowed/>"); //$NON-NLS-1$
		out.println("\t</information>"); //$NON-NLS-1$
		out.println("\t<security>"); //$NON-NLS-1$
		out.println("\t\t<all-permissions/>"); //$NON-NLS-1$
		out.println("\t</security>"); //$NON-NLS-1$
		out.println("\t<component-desc/>"); //$NON-NLS-1$
		out.println("\t<resources>"); //$NON-NLS-1$
		out.println("\t\t<j2se version=\"" + j2se + "\" />"); //$NON-NLS-1$ //$NON-NLS-2$
		out.println("\t</resources>"); //$NON-NLS-1$
	}

	private void writeEpilogue() {
		out.println("</jnlp>"); //$NON-NLS-1$
	}

	private boolean isMatching(String candidateValues, String siteValues) {
		if (candidateValues == null)
			return true;
		if (siteValues == null)
			return false;
		if ("*".equals(candidateValues))return true; //$NON-NLS-1$
		if ("".equals(candidateValues))return true; //$NON-NLS-1$
		StringTokenizer siteTokens = new StringTokenizer(siteValues, ","); //$NON-NLS-1$
		//$NON-NLS-1$	
		while (siteTokens.hasMoreTokens()) {
			StringTokenizer candidateTokens = new StringTokenizer(candidateValues, ","); //$NON-NLS-1$
			String siteValue = siteTokens.nextToken();
			while (candidateTokens.hasMoreTokens()) {
				if (siteValue.equalsIgnoreCase(candidateTokens.nextToken()))
					return true;
			}
		}
		return false;
	}

	private boolean isValidEnvironment(String os, String ws, String arch) {
		if (configs.length == 0)
			return true;
		for (int i = 0; i < configs.length; i++) {
			if (isMatching(os, configs[i].getOs()) && isMatching(ws, configs[i].getWs()) && isMatching(arch, configs[i].getArch()))
				return true;
		}
		return false;
	}

	private void setConfigInfo(String spec) {
		if (spec != null && spec.startsWith("$")) { //$NON-NLS-1$
			configs = new Config[0];
			return;
		}
		if (spec == null) {
			configs = new Config[] {Config.genericConfig()};
			return;
		}
		StringTokenizer tokens = new StringTokenizer(spec, "&"); //$NON-NLS-1$
		int configNbr = tokens.countTokens();
		ArrayList configInfos = new ArrayList(configNbr);
		while (tokens.hasMoreElements()) {
			String aConfig = tokens.nextToken();
			StringTokenizer configTokens = new StringTokenizer(aConfig, ","); //$NON-NLS-1$
			if (configTokens.countTokens() == 3) {
				Config toAdd = new Config(configTokens.nextToken().trim(), configTokens.nextToken().trim(), configTokens.nextToken().trim());
				if (toAdd.equals(Config.genericConfig()))
					toAdd = Config.genericConfig();
				configInfos.add(toAdd);
			}
		}
		if (configInfos.size() == 0)
			configInfos.add(Config.genericConfig());
		configs = (Config[]) configInfos.toArray(new Config[configInfos.size()]);
	}
}
