/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.core.internal.model;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.internal.runtime.Policy;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.model.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;

public class RegistryLoader {
	private Factory factory;

	// debug support
	private boolean debug = false;
	private long startTick = (new java.util.Date()).getTime(); // used for performance timings
	private long lastTick = startTick;

	private RegistryLoader(Factory factory, boolean debug) {
		super();
		this.debug = debug;
		this.factory = factory;
	}

	private void debug(String msg) {
		long thisTick = System.currentTimeMillis();
		System.out.println("RegistryLoader: " + msg + " [+" + (thisTick - lastTick) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		lastTick = thisTick;
	}

	private String[] getPathMembers(URL path) {
		String[] list = null;
		String protocol = path.getProtocol();
		if (protocol.equals("file")) { //$NON-NLS-1$
			list = (new File(path.getFile())).list();
		} else {
			// XXX: attempt to read URL and see if we got html dir page
		}
		return list == null ? new String[0] : list;
	}

	/**
	 * Reports an error and returns true.
	 */
	private boolean parseProblem(String message) {
		factory.error(new Status(IStatus.WARNING, Platform.PI_RUNTIME, Platform.PARSE_PROBLEM, message, null));
		return true;
	}

	private PluginRegistryModel parseRegistry(URL[] pluginPath) {
		long startTick = System.currentTimeMillis();
		PluginRegistryModel result = processManifestFiles(pluginPath);
		if (InternalPlatform.DEBUG) {
			long endTick = System.currentTimeMillis();
			debug("Parsed Registry: " + (endTick - startTick) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return result;
	}

	public static PluginRegistryModel parseRegistry(URL[] pluginPath, Factory factory, boolean debug) {
		return new RegistryLoader(factory, debug).parseRegistry(pluginPath);
	}

	private PluginModel processManifestFile(URL manifest) {
		InputStream is = null;
		try {
			is = manifest.openStream();
		} catch (IOException e) {
			if (debug)
				debug("No plugin found for: " + manifest); //$NON-NLS-1$
			return null;
		}
		PluginModel result = null;
		try {
			try {
				InputSource in = new InputSource(is);
				// Give the system id a value in case we want it for
				// error reporting within the parser.
				in.setSystemId(manifest.getFile());
				result = new PluginParser((Factory) factory).parsePlugin(in);
			} finally {
				is.close();
			}
		} catch (SAXParseException se) {
			/* exception details logged by parser */
			factory.error(new Status(IStatus.WARNING, Platform.PI_RUNTIME, Platform.PARSE_PROBLEM, Policy.bind("parse.errorProcessing", manifest.toString()), null)); //$NON-NLS-1$
		} catch (Exception e) {
			factory.error(new Status(IStatus.WARNING, Platform.PI_RUNTIME, Platform.PARSE_PROBLEM, Policy.bind("parse.errorProcessing", manifest.toString() + ":  " + e.getMessage()), null)); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return result;
	}

	private PluginRegistryModel processManifestFiles(URL[] pluginPath) {
		PluginRegistryModel result = factory.createPluginRegistry();
		for (int i = 0; i < pluginPath.length; i++)
			processPluginPathEntry(result, pluginPath[i]);
		return result;
	}

	private void processPluginPathEntry(PluginRegistryModel registry, URL location) {
		if (debug)
			debug("Path - " + location); //$NON-NLS-1$
		if (location.getFile().endsWith("/")) { //$NON-NLS-1$
			// directory entry - search for plugins
			String[] members = getPathMembers(location);
			for (int j = 0; j < members.length; j++) {
				boolean found = false;
				try {
					found = processPluginPathFile(registry, new URL(location, members[j] + "/plugin.xml")); //$NON-NLS-1$
					if (!found)
						found = processPluginPathFile(registry, new URL(location, members[j] + "/fragment.xml")); //$NON-NLS-1$
				} catch (MalformedURLException e) {
					// Skip bad URLs
				}
				if (debug)
					debug(found ? "Processed - " : "Processed (not found) - " + members[j]); //$NON-NLS-1$ //$NON-NLS-2$
			}
		} else {
			// specific file entry - load the given file
			boolean found = processPluginPathFile(registry, location);
			if (debug)
				debug(found ? "Processed - " : "Processed (not found) - " + location); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * @return true if a file was found at the given location, and false otherwise.
	 */
	private boolean processPluginPathFile(PluginRegistryModel registry, URL location) {
		PluginModel entry = processManifestFile(location);
		if (entry == null)
			return false;
		// Make sure all the required fields are here.
		// This prevents us from things like NullPointerExceptions
		// when we are assuming a field exists.
		if (!requiredPluginModel(entry, location)) {
			entry = null;
			return false;
		}
		entry.setVersion(getQualifiedVersion(entry, location)); // check for version qualifier
		if (entry instanceof PluginDescriptorModel) {
			if (entry.getId() == null || entry.getVersion() == null) {
				return parseProblem(Policy.bind("parse.nullPluginIdentifier", location.toString())); //$NON-NLS-1$
			}
			//skip duplicate entries
			if (registry.getPlugin(entry.getId(), entry.getVersion()) != null) {
				return parseProblem(Policy.bind("parse.duplicatePlugin", entry.getId(), location.toString())); //$NON-NLS-1$
			}
			registry.addPlugin((PluginDescriptorModel) entry);
		} else {
			if (entry.getId() == null || entry.getVersion() == null) {
				return parseProblem(Policy.bind("parse.nullFragmentIdentifier", location.toString())); //$NON-NLS-1$
			}
			if (entry instanceof PluginFragmentModel) {
				registry.addFragment((PluginFragmentModel) entry);
			} else {
				return parseProblem(Policy.bind("parse.unknownEntry", location.toString())); //$NON-NLS-1$
			}
		}
		String url = location.toString();
		url = url.substring(0, 1 + url.lastIndexOf('/'));
		entry.setRegistry(registry);
		entry.setLocation(url);
		// this is for the registry cache
		// InternalPlatform.addLastModifiedTime(location.getFile(), new File(location.getFile()).lastModified());
		return true;
	}

	private String getQualifiedVersion(PluginModel entry, URL base) {
		if (entry == null || entry.getVersion() == null || entry.getId() == null)
			return null;

		InputStream is = null;
		try {
			// check to see if we have buildmanifest.properties for this plugin
			URL manifest = null;
			manifest = new URL(base, "buildmanifest.properties"); //$NON-NLS-1$
			Properties props = new Properties();
			is = manifest.openStream();
			props.load(is);

			// lookup qualifier for this plugin and "morph" the identifier if needed
			String key = "plugin@" + entry.getId(); //$NON-NLS-1$
			String qualifier = props.getProperty(key);
			if (qualifier == null)
				return entry.getVersion();
			PluginVersionIdentifier v = new PluginVersionIdentifier(entry.getVersion());
			if (!v.getQualifierComponent().equals("")) //$NON-NLS-1$
				return entry.getVersion();
			else
				return (new PluginVersionIdentifier(v.getMajorComponent(), v.getMinorComponent(), v.getServiceComponent(), qualifier)).toString();
		} catch (Exception e) {
			return entry.getVersion();
		} finally {
			if (is != null)
				try {
					is.close();
				} catch (IOException e) {
					// Don't throw anything back if the close fails
				}
		}
	}

	private boolean requiredPluginModel(PluginModel plugin, URL location) {
		String name = plugin.getName();
		String id = plugin.getId();
		String version = plugin.getVersion();
		int nameLength = name == null ? 0 : name.length();
		int idLength = id == null ? 0 : id.length();
		int versionLength = version == null ? 0 : version.length();

		if (nameLength <= 0) {
			parseProblem(Policy.bind("parse.missingPluginName", location.toString())); //$NON-NLS-1$
			return false;
		}
		if (idLength <= 0) {
			parseProblem(Policy.bind("parse.missingPluginId", location.toString())); //$NON-NLS-1$
			return false;
		}
		if (versionLength <= 0) {
			parseProblem(Policy.bind("parse.missingPluginVersion", location.toString())); //$NON-NLS-1$
			return false;
		}

		if (plugin instanceof PluginFragmentModel) {
			String pluginName = ((PluginFragmentModel) plugin).getPlugin();
			String pluginVersion = ((PluginFragmentModel) plugin).getPluginVersion();
			int pNameLength = pluginName == null ? 0 : pluginName.length();
			int pNameVersion = pluginVersion == null ? 0 : pluginVersion.length();
			if (pNameLength <= 0) {
				parseProblem(Policy.bind("parse.missingFPName", location.toString())); //$NON-NLS-1$
				return false;
			}
			if (pNameVersion <= 0) {
				parseProblem(Policy.bind("parse.missingFPVersion", location.toString())); //$NON-NLS-1$
				return false;
			}
		}
		return true;
	}
}