/*******************************************************************************
 * 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 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.internal.configurator;

import java.net.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import org.eclipse.core.runtime.*;
import org.eclipse.update.configurator.*;
import org.w3c.dom.*;


public class Configuration implements IConfigurationConstants {
	
	private HashMap sites = new HashMap();
	private Date date;
	private long lastModified; // needed to account for file system limitations
	private URL url;
	private boolean transientConfig;
	private boolean isDirty;
	private Configuration linkedConfig; // shared configuration
	
	public Configuration() {
		this(new Date());
		// the config is created now or out of a platform.xml without a date
		isDirty = true;
	}
	public Configuration(Date date)  {
		this.date = date;
	}
	
	public void setURL(URL url) {
		this.url = url;
	}
	
	public URL getURL() {
		return url;
	}
	
	public void setLinkedConfig(Configuration linkedConfig) {
		this.linkedConfig = linkedConfig;
		// make all the sites read-only
		SiteEntry[] linkedSites = linkedConfig.getSites();
		for (int i=0; i<linkedSites.length; i++)
			linkedSites[i].setUpdateable(false);
	}
	
	public Configuration getLinkedConfig() {
		return linkedConfig;
	}
	
	/**
	 * @return true if the config needs to be saved
	 */
	public boolean isDirty() {
		return isDirty;
	}
	
	public void setDirty(boolean dirty) {
		isDirty = dirty;
	}
	
	public void addSiteEntry(String url, SiteEntry site) {
		url = Utils.canonicalizeURL(url);
		// only add the same site once
		if (sites.get(url) == null && (linkedConfig == null || linkedConfig.sites.get(url) == null)) {
			site.setConfig(this);
			sites.put(url, site);
		}
	}
	
	public void removeSiteEntry(String url) {
		url =Utils.canonicalizeURL(url);		
		sites.remove(url);
	}
	
	public SiteEntry getSiteEntry(String url) {
		url = Utils.canonicalizeURL(url);		
		SiteEntry site = (SiteEntry)sites.get(url);
		if (site == null && linkedConfig != null)
			site = linkedConfig.getSiteEntry(url);
		return site;
	}
	
	public SiteEntry[] getSites() {
		if (linkedConfig == null)
			return (SiteEntry[]) sites.values().toArray(new SiteEntry[sites.size()]);
		ArrayList combinedSites = new ArrayList(sites.values());
		combinedSites.addAll(linkedConfig.sites.values());
		return (SiteEntry[]) combinedSites.toArray(new SiteEntry[combinedSites.size()]);
	}
	
	public Element toXML(Document doc) throws CoreException {	
		try {
			Element configElement = doc.createElement(CFG);

			configElement.setAttribute(CFG_VERSION, VERSION);
			configElement.setAttribute(CFG_DATE, String.valueOf(date.getTime()));
			String transitory = isTransient() ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
			configElement.setAttribute(CFG_TRANSIENT, transitory);
						
			if (linkedConfig != null) {
				// make externalized URL install relative 
				configElement.setAttribute(CFG_SHARED_URL, Utils.makeRelative(Utils.getInstallURL(), linkedConfig.getURL()).toExternalForm());
			}

			// collect site entries
			SiteEntry[] list = (SiteEntry[]) sites.values().toArray(new SiteEntry[0]);
			for (int i = 0; i < list.length; i++) {
				if (linkedConfig != null && linkedConfig.getSiteEntry(list[i].getURL().toExternalForm()) != null)
					continue;
				Element siteElement = list[i].toXML(doc);
				configElement.appendChild(siteElement);
			}
			
			return configElement;
			
		} catch (Exception e) {
			throw Utils.newCoreException("", e); //$NON-NLS-1$
		} 
	}
	
	public boolean isTransient() {
		return transientConfig;
	}
	
	public void setTransient(boolean isTransient) {
		this.transientConfig = isTransient;
	}
	
	public Date getDate() {
		return date;
	}
	
	public void setDate(Date date) {
		this.date = date;
	}
	
	public boolean unconfigureFeatureEntry(IPlatformConfiguration.IFeatureEntry feature) {
		SiteEntry[] sites = getSites();
		for (int i=0; i<sites.length; i++)
			if (sites[i].unconfigureFeatureEntry(feature))
				return true;
		return false;
	}
	
	public void setLastModified(long lastModified) {
		this.lastModified = lastModified;
	}
	
	public long lastModified() {
		return (lastModified != 0) ? lastModified : date.getTime();
	}
}
