/*******************************************************************************
 * 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.update.core.model;

import java.lang.reflect.*;
import java.net.*;
import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.core.*;

/**
 * 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>
 */
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(), Policy.bind("ModelObject.ModelReadOnly"));	//$NON-NLS-1$
	}

	/**
	 * 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()); //$NON-NLS-1$
		}
		return bundle;
	}

	/**
	 * Method getPropertyName.
	 * @return String
	 */
	protected String getPropertyName() {
		return Feature.FEATURE_FILE;
	}

}
