/*******************************************************************************
 *  Copyright (c) 2000, 2010 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
 *******************************************************************************/
package org.eclipse.update.core.model;

import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.update.core.Feature;
import org.eclipse.update.core.SiteManager;
import org.eclipse.update.internal.core.Messages;
import org.eclipse.update.internal.core.UpdateCore;
import org.eclipse.update.internal.core.UpdateManagerUtils;

/**
 * Root model object. Extended by all model objects.
 * <p>
 * This class cannot be instantiated and must be subclassed.
 * </p>
 * <p>
 * <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to
 * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
 * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
 * (repeatedly) as the API evolves.
 * </p>
 * @deprecated The org.eclipse.update component has been replaced by Equinox p2.
 * This API will be deleted in a future release. See bug 311590 for details.
 */
public abstract class ModelObject extends PlatformObject {

	private boolean readOnly = false;

	private static final String KEY_PREFIX = "%"; //$NON-NLS-1$
	private static final String KEY_DOUBLE_PREFIX = KEY_PREFIX + KEY_PREFIX;

	private static Map bundles;

	/**
	 * Creates a base model object.
	 * 
	 * @since 2.0
	 */
	protected ModelObject() {
	}

	/**
	 * Checks that this model object is writeable.  A runtime exception
	 * is thrown if it is not.
	 * 
	 * @since 2.0
	 */
	protected final void assertIsWriteable() {
		Assert.isTrue(!isReadOnly(), Messages.ModelObject_ModelReadOnly);	
	}

	/**
	 * Sets this model object and all of its descendents to be read-only.
	 * Subclasses may extend this implementation.
	 * 
	 * @see #isReadOnly
	 * @since 2.0
	 */
	public void markReadOnly() {
		readOnly = true;
	}

	/**
	 * Returns whether or not this model object is read-only.
	 * 
	 * @return <code>true</code> if this model object is read-only,
	 *		<code>false</code> otherwise
	 * @see #markReadOnly
	 * @since 2.0
	 */
	public boolean isReadOnly() {
		return readOnly;
	}

	/**
	 * Delegate setting of read-only
	 *
	 * @param o object to delegate to. Must be of type ModelObject.
	 * @see #isReadOnly
	 * @since 2.0
	 */
	protected void markReferenceReadOnly(ModelObject o) {
		if (o == null)
			return;
		o.markReadOnly();
	}

	/**
	 * Delegate setting of read-only
	 *
	 * @param o object array to delegate to. Each element must be of type ModelObject.
	 * @see #isReadOnly
	 * @since 2.0
	 */
	protected void markListReferenceReadOnly(ModelObject[] o) {
		if (o == null)
			return;
		for (int i = 0; i < o.length; i++) {
			o[i].markReadOnly();
		}
	}

	/**
	 * Resolve the model element. This method allows any relative URL strings
	 * to be resolved to actual URL. It also allows any translatable strings
	 * to be localized.
	 * 
	 * Subclasses need to override this method to perform the actual resolution.
	 * @param base base URL.
	 * @param bundleURL resource bundle URL.
	 * @exception MalformedURLException
	 * @since 2.0
	 */
	public void resolve(URL base, URL bundleURL) throws MalformedURLException {
		return;
	}

	/**
	 * Delegate resolution to referenced model
	 *
	 * @param o object to delegate to. Must be of type ModelObject.
	 * @param url base URL.
	 * @param bundleURL resource bundle URL.
	 * @exception MalformedURLException
	 * @since 2.0
	 */
	protected void resolveReference(ModelObject o, URL url, URL bundleURL) throws MalformedURLException {
		if (o == null)
			return;
		o.resolve(url, bundleURL);
	}

	/**
	 * Delegate resolution to list of referenced models
	 *
	 * @param o object array to delegate to. Each element must be of type ModelObject.
	 * @param url base URL.
	 * @param bundleURL resource bundle URL.
	 * @exception MalformedURLException
	 * @since 2.0
	 */
	protected void resolveListReference(ModelObject[] o, URL url, URL bundleURL) throws MalformedURLException {
		if (o == null)
			return;
		for (int i = 0; i < o.length; i++) {
			o[i].resolve(url, bundleURL);
		}
	}

	/**
	 * Resolve a URL based on context
	 *
	 * @param context base URL.
	 * @param bundleURL resource bundle URL.
	 * @param urlString url string from model.
	 * @return URL, or <code>null</code>.
	 * @exception MalformedURLException
	 * @since 2.0
	 */
	protected URL resolveURL(URL context, URL bundleURL, String urlString) throws MalformedURLException {

		// URL string was not specified
		if (urlString == null || urlString.trim().equals("")) //$NON-NLS-1$
			return null;

		// check to see if we have NL-sensitive URL
		String resolvedUrlString = resolveNLString(bundleURL, urlString);

		resolvedUrlString = resolvePlatfromConfiguration(resolvedUrlString);

		// if we don't have a base url, use only the supplied string
		if (context == null)
			return new URL(resolvedUrlString);

		// otherwise return new URL in context of base URL
		return new URL(context, resolvedUrlString);
	}
	/**
	 * Resolves the URL based on platfrom Configuration
	 * $os$\$ws$\license.txt will become
	 * win32\win32\license.txt on a system where os=win32 and ws=win32
	 * 
	 * @param resolvedUrlString
	 * @return String
	 */
	private String resolvePlatfromConfiguration(String resolvedUrlString) {
		int osIndex = resolvedUrlString.indexOf("$os$"); //$NON-NLS-1$
		if (osIndex != -1)
			return getExtendedString(resolvedUrlString);

		int wsIndex = resolvedUrlString.indexOf("$ws$"); //$NON-NLS-1$
		if (wsIndex != -1)
			return getExtendedString(resolvedUrlString);

		int nlIndex = resolvedUrlString.indexOf("$nl$"); //$NON-NLS-1$
		if (nlIndex != -1)
			return getExtendedString(resolvedUrlString);

		int archIndex = resolvedUrlString.indexOf("$arch$"); //$NON-NLS-1$
		if (archIndex != -1)
			return getExtendedString(resolvedUrlString);

		return resolvedUrlString;
	}

	private String getExtendedString(String resolvedUrlString) {
		IPath path = new Path(resolvedUrlString);
		path = getExpandedPath(path);
		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_WARNINGS) {
			UpdateCore.warn("Resolved :" + resolvedUrlString + " as:" + path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
		}

		return path.toOSString();
	}

	private IPath getExpandedPath(IPath path) {
		String first = path.segment(0);
		if (first != null) {
			IPath rest = getExpandedPath(path.removeFirstSegments(1));
			if (first.equals("$ws$")) { //$NON-NLS-1$
				path = new Path(SiteManager.getWS()).append(rest);
			} else if (first.equals("$os$")) { //$NON-NLS-1$
				path = new Path(SiteManager.getOS()).append(rest);
			} else if (first.equals("$nl$")) { //$NON-NLS-1$
				path = new Path(SiteManager.getNL()).append(rest);
			} else if (first.equals("$arch$")) { //$NON-NLS-1$
				path = new Path(SiteManager.getOSArch()).append(rest);
			}
		}
		return path;
	}

	/**
	 * Returns a resource string corresponding to the given argument 
	 * value and bundle.
	 * If the argument value specifies a resource key, the string
	 * is looked up in the given resource bundle. If the argument does not
	 * specify a valid key, the argument itself is returned as the
	 * resource string. The key lookup is performed against the
	 * specified resource bundle. If a resource string 
	 * corresponding to the key is not found in the resource bundle
	 * the key value, or any default text following the key in the
	 * argument value is returned as the resource string.
	 * A key is identified as a string begining with the "%" character.
	 * Note that the "%" character is stripped off prior to lookup
	 * in the resource bundle.
	 * <p>
	 * For example, assume resource bundle plugin.properties contains
	 * name = Project Name
	 * <pre>
	 *     resolveNLString(b,"Hello World") returns "Hello World"</li>
	 *     resolveNLString(b,"%name") returns "Project Name"</li>
	 *     resolveNLString(b,"%name Hello World") returns "Project Name"</li>
	 *     resolveNLString(b,"%abcd Hello World") returns "Hello World"</li>
	 *     resolveNLString(b,"%abcd") returns "%abcd"</li>
	 *     resolveNLString(b,"%%name") returns "%name"</li>
	 * </pre>
	 * </p>
	 * 
	 * @param bundleURL resource bundle url.
	 * @param string translatable string from model
	 * @return string, or <code>null</code>
	 * @since 2.0
	 */
	protected String resolveNLString(URL bundleURL, String string) {

		if (string == null)
			return null;

		String s = string.trim();

		if (s.equals("")) //$NON-NLS-1$
			return string;

		if (!s.startsWith(KEY_PREFIX))
			return string;

		if (s.startsWith(KEY_DOUBLE_PREFIX))
			return s.substring(1);

		int ix = s.indexOf(" "); //$NON-NLS-1$
		String key = ix == -1 ? s : s.substring(0, ix);
		String dflt = ix == -1 ? s : s.substring(ix + 1);

		ResourceBundle b = getResourceBundle(bundleURL);

		if (b == null)
			return dflt;

		try {
			return b.getString(key.substring(1));
		} catch (MissingResourceException e) {
			return dflt;
		}
	}

	/**
	 * Returns a concrete array type for the elements of the specified
	 * list. The method assumes all the elements of the list are the same
	 * concrete type as the first element in the list.
	 * 
	 * @param l list
	 * @return concrete array type, or <code>null</code> if the array type
	 * could not be determined (the list is <code>null</code> or empty)
	 * @since 2.0
	 */
	protected Object[] arrayTypeFor(List l) {
		if (l == null || l.size() == 0)
			return null;
		return (Object[]) Array.newInstance(l.get(0).getClass(), 0);
	}

	/**
	 * Returns a concrete array type for the elements of the specified
	 * set. The method assumes all the elements of the set are the same
	 * concrete type as the first element in the set.
	 * 
	 * @param s set
	 * @return concrete array type, or <code>null</code> if the array type
	 * could not be determined (the set is <code>null</code> or empty)
	 * @since 2.0
	 */
	protected Object[] arrayTypeFor(Set s) {
		if (s == null || s.size() == 0)
			return null;
		Iterator i = s.iterator();
		return (Object[]) Array.newInstance(i.next().getClass(), 0);
	}

	/**
		* Helper method to access resouce bundle for feature. The default 
		* implementation attempts to load the appropriately localized 
		* feature.properties file.
		* 
		* @param url base URL used to load the resource bundle.
		* @return resource bundle, or <code>null</code>.
		* @since 2.0
		*/
	protected ResourceBundle getResourceBundle(URL url) {

		if (url == null)
			return null;

		if (bundles == null) {
			bundles = new HashMap();
		} else {
			ResourceBundle bundle = (ResourceBundle) bundles.get(url.toExternalForm());
			if (bundle != null)
				return bundle;
		}

		ResourceBundle bundle = null;
		try {
			url = UpdateManagerUtils.asDirectoryURL(url);
			ClassLoader l = new URLClassLoader(new URL[] { url }, null);
			bundle = ResourceBundle.getBundle(getPropertyName(), Locale.getDefault(), l);
			bundles.put(url.toExternalForm(), bundle);
		} catch (MissingResourceException e) {
			UpdateCore.warn(e.getLocalizedMessage() + ":" + url.toExternalForm()); //$NON-NLS-1$
		} catch (MalformedURLException e) {
			UpdateCore.warn(e.getLocalizedMessage()); 
		}
		return bundle;
	}

	/**
	 * Method getPropertyName.
	 * @return String
	 */
	protected String getPropertyName() {
		return Feature.FEATURE_FILE;
	}

}
