/*******************************************************************************
 * Copyright (c) 2000, 2004 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 lastTick = System.currentTimeMillis();//used for performance timing

	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;
	}
}