package org.eclipse.update.internal.core;
/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.TreeSet;

import org.eclipse.core.internal.boot.LaunchInfo;
import org.eclipse.core.internal.boot.LaunchInfo.VersionedIdentifier;
import org.eclipse.core.internal.boot.update.IComponentDescriptor;
import org.eclipse.core.internal.boot.update.IComponentEntryDescriptor;
import org.eclipse.core.internal.boot.update.IFragmentEntryDescriptor;
import org.eclipse.core.internal.boot.update.IInstallable;
import org.eclipse.core.internal.boot.update.IPluginEntryDescriptor;
import org.eclipse.core.internal.boot.update.IProductDescriptor;
import org.eclipse.core.internal.boot.update.IUMRegistry;
import org.eclipse.core.internal.boot.update.IURLNamePair;
import org.eclipse.core.internal.boot.update.LogStoreException;
import org.eclipse.core.internal.boot.update.UMEclipseTree;
import org.eclipse.core.internal.boot.update.UMRegistryManager;
import org.eclipse.core.internal.boot.update.UpdateManagerConstants;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.update.internal.ui.JarVerificationService;

/**
 * Update Manager updates a workstation in one of three modes:
 * <ol>
 * <li>local</li>
 * <li>remote</li>
 * <li>remote cached</li>
 * </ol>
 * Usage:
 * <ol>
 * <li>Create an instance of this class</li>
 * <li>Set persistent properties as required</li>
 * <ul>
 * <li>mode</li>
 * <li>update log URL</li>
 * <li>history log URL</li>
 * </ul>
 * <li>Call the initialize function</li>
 * <li>Call the update function</li>
 * </ol>
 * Persistent properties are loaded before any are changed, and saved after any
 * are changed.
 */

public class UpdateManager {

	// Package name for this class
	// Used by UpdateManagerStrings to obtain its resource bundle properties file
	//---------------------------------------------------------------------------
	public static final String _strPackageName = "org.eclipse.update.internal.core";
	public static UpdateManager _updateManagerInstance = null;
	
	// Persistent properties
	//----------------------
	protected int    _iMode         = UpdateManagerConstants.MODE_LOCAL;
	protected String _strUpdateLogURL  = null;
	protected String _strHistoryLogURL = null;

	// Instance state data
	//--------------------
	protected UMRegistryManager _registryManager = null;
	protected UMSessionManager  _sessionManager  = null;
	protected Shell             _shell           = null;
	
	protected JarVerificationService _jarVerifier = null;
/**
 * Constructs an instance of this class, then initializes by loading its persistent properties
 */
public UpdateManager() {
}
/**
 * Constructs an instance of this class, then initializes by loading its persistent properties
 */
public UpdateManager( Shell shell ) {
	_updateManagerInstance = this;
	_shell = shell;
}
/**
 * Deletes all files in the staging area.
 */
public void cleanup() {
	String strStagingDirectory = UMEclipseTree.getFileInPlatformString(UMEclipseTree.getStagingArea());

	File fileStagingDirectory = new File(strStagingDirectory);

	if (fileStagingDirectory.exists() == true) {
		File[] files = fileStagingDirectory.listFiles();
		for (int i = 0; i < files.length; ++i) {
			if (files[i].isDirectory() == true) {
				cleanupDirectory(files[i]);
			}
			boolean bSuccessful = files[i].delete();
			
		}
	}
}
/**
 */
public static void cleanupDirectory(File fileDirectory) {

	File[] files = fileDirectory.listFiles();
	
	for (int i = 0; i < files.length; ++i) {
		if (files[i].isDirectory() == true) {
			cleanupDirectory(files[i]);
		}

		boolean bSuccessful = files[i].delete();
//		if (!bSuccessful)
//			System.out.println("ooops!" + files[i]);
	}
}
/**
 */
public UMSessionManagerSession createSession(IInstallable[] descriptors, boolean bVerifyJars) throws UpdateManagerException {

	// FOR NOW DO NOT DO JAR VERIFICATION
	//-----------------------------------
	bVerifyJars = false;

	// Create a new update session
	//----------------------------
	UMSessionManagerSession session = _sessionManager.createUpdateSession();

	// Create a definer that can define the operations required
	//---------------------------------------------------------
	ISessionDefiner sessionDefiner = new UMSessionDefinerReferenceUpdate();
	
	// Define a set of operations
	//---------------------------
	sessionDefiner.defineOperations(session, descriptors, bVerifyJars);

	// Save the update log
	//--------------------
	try {
		_sessionManager.saveUpdateLog();
	}
	catch (LogStoreException ex) {
		throw new UpdateManagerException(ex.getMessage());
	}

	return session;
}
/**
 * Updates the local machine by:
 * <ol>
 * <li>defining the operations</li>
 * <li>downloading any new objects</li>
 * <li>applying any downloaded updates</li>
 * <li>displaying a progress monitor</li>
 * </ol>
 */
public UMSessionManagerSession executeSession( UMSessionManagerSession session, IProgressMonitor progressMonitor ) throws UpdateManagerException {

	// Throw any exception when complete
	//----------------------------------
	UpdateManagerException umException = null;
	
	// Execute the session
	//--------------------
	_sessionManager.executeSession( session, progressMonitor );

	// Move successful sessions from update log to history log
	//--------------------------------------------------------
	try {
		_sessionManager.updateAndSaveLogs();
	}
	catch (LogStoreException ex) {
		if (umException != null) {
			umException = new UpdateManagerException("S_Unable_to_save_update_logs");
		}
	}

	// Throw any exceptions found
	//---------------------------
	if (umException != null) {
		throw umException;
	}

	return session;
}
/**
 * Updates the local machine by:
 * <ol>
 * <li>defining the operations</li>
 * <li>downloading any new objects</li>
 * <li>applying any downloaded updates</li>
 * <li>displaying a progress monitor</li>
 * </ol>
 */
public UMSessionManagerSession executeSessionUndo( UMSessionManagerSession session, IProgressMonitor progressMonitor ) throws UpdateManagerException {

	// Throw any exception when complete
	//----------------------------------
	UpdateManagerException umException = null;
	
	// Execute the session
	//--------------------
	_sessionManager.executeSessionUndo( session, progressMonitor );

	// Move successful sessions from update log to history log
	//--------------------------------------------------------
	try {
		_sessionManager.updateAndSaveLogs();
	}
	catch (LogStoreException ex) {
		if (umException != null) {
			umException = new UpdateManagerException("S Unable to save update logs");
		}
	}

	// Throw any exceptions found
	//---------------------------
	if (umException != null) {
		throw umException;
	}

	return session;
}
/**
 */
public static UpdateManager getCurrentInstance() {
	return _updateManagerInstance;
}
/**
 * Takes a string with an Id + '_' + Version, and returns the Id.
 */
private String getIdFromInfoString(String strInfo) {

	String strId = null;

	int iIndex = strInfo.lastIndexOf('_');
	
	if (iIndex >= 0) {
		strId = strInfo.substring(0, iIndex);
	}

	else {
		strId = strInfo;
	}

	return strId;
}
// return the jar verifier

public JarVerificationService getJarVerifier() {
	if (_jarVerifier == null)	
		_jarVerifier = new JarVerificationService( _shell );
	return _jarVerifier;
}
/**
 * Returns a list of components that require updating by:
 *<ol>
 *<li>Loading all product/component manifests from .install/tree </li>
 *<li>Determining which components require updating by:</li>
 *<ol>
 *<li>Collecting update URLs from each component</li>
 *<li>Collecting update URLs from products that components are a part of</li>
 *</ol>
 *<li>Determining what updates are available by:</li>
 *<ol>
 *<li>Accessing the update URL</li>
 *<li>Determining if the component is a newer version of the existing one</li>
 *</ol>
 *<li>
 *</ol>
 */
public IURLNamePair[] getLocalDiscoveryURLs() {

	IURLNamePair[] urlNPs = null;
	
	// Obtain the local registry
	//--------------------------
	IUMRegistry registry = _registryManager.getLocalRegistry();

	// Create a list of all URLs
	//--------------------------
	TreeSet setURLs = new TreeSet( new UpdateManagerURLComparator() );

	// Obtain a list of all installed components
	//------------------------------------------
	IComponentDescriptor[] componentDescriptors = registry.getComponentDescriptors();

	// Obtain a list of discovery URLs
	//--------------------------------
	for (int i = 0; i < componentDescriptors.length; ++i) {
		urlNPs = componentDescriptors[i].getDiscoveryURLs();

		for (int j = 0; j < urlNPs.length; ++j) {
			setURLs.add(urlNPs[j]);
		}
	}

	// Obtain a list of all installed products
	//----------------------------------------
	IProductDescriptor[] productDescriptors = registry.getProductDescriptors();

	// Obtain a list of discovery URLs
	//--------------------------------
	for (int i = 0; i < productDescriptors.length; ++i) {
		urlNPs = productDescriptors[i].getDiscoveryURLs();

		for (int j = 0; j < urlNPs.length; ++j) {
			setURLs.add(urlNPs[j]);
		}
	}

	urlNPs = new IURLNamePair[ setURLs.size() ];
	System.arraycopy(setURLs.toArray(), 0, urlNPs, 0, setURLs.size() );
	
	return urlNPs;
}
/**
 * Returns a list of components that require updating by:
 *<ol>
 *<li>Loading all product/component manifests from .install/tree </li>
 *<li>Determining which components require updating by:</li>
 *<ol>
 *<li>Collecting update URLs from each component</li>
 *<li>Collecting update URLs from products that components are a part of</li>
 *</ol>
 *<li>Determining what updates are available by:</li>
 *<ol>
 *<li>Accessing the update URL</li>
 *<li>Determining if the component is a newer version of the existing one</li>
 *</ol>
 *<li>
 *</ol>
 */
public IURLNamePair[] getLocalUpdateURLs() {

	IURLNamePair[] urlNPs = null;
	
	// Obtain the local registry
	//--------------------------
	IUMRegistry registry = _registryManager.getLocalRegistry();

	// Create a list of all URLs
	//--------------------------
	TreeSet setURLs = new TreeSet( new UpdateManagerURLComparator() );

	// Obtain a list of all installed components
	//------------------------------------------
	IComponentDescriptor[] componentDescriptors = registry.getComponentDescriptors();

	// Obtain a list of discovery URLs
	//--------------------------------
	for (int i = 0; i < componentDescriptors.length; ++i) {
		urlNPs = componentDescriptors[i].getUpdateURLs();

		for (int j = 0; j < urlNPs.length; ++j) {
			setURLs.add(urlNPs[j]);
		}
	}

	// Obtain a list of all installed products
	//----------------------------------------
	IProductDescriptor[] productDescriptors = registry.getProductDescriptors();

	// Obtain a list of discovery URLs
	//--------------------------------
	for (int i = 0; i < productDescriptors.length; ++i) {
		urlNPs = productDescriptors[i].getUpdateURLs();

		for (int j = 0; j < urlNPs.length; ++j) {
			setURLs.add(urlNPs[j]);
		}
	}

	urlNPs = new IURLNamePair[ setURLs.size() ];
	System.arraycopy(setURLs.toArray(), 0, urlNPs, 0, setURLs.size() );
	
	return urlNPs;
}
// return the local (current) registry

public IUMRegistry getRegistryAt(URL url) {
	
	return _registryManager.getRegistryAt( url );
}
/**
 */
public UMRegistryManager getRegistryManager() {
	return _registryManager;
}
/**
 * Initializes the update and history log URLs,creates a session manager,
 * and creates a registry manager.
 */
public void initialize() throws UpdateManagerException{

	// Obtain install URL
	//-------------------
	URL urlBase = UMEclipseTree.getBaseInstallURL();
	String strUrlBase = urlBase.toExternalForm();
	String strUrlInstall = strUrlBase + "install/";

	String strUrlUpdateLog = strUrlInstall + "update.log";
	String strUrlHistoryLog = strUrlInstall + "history.log";

	setUpdateLogURL(strUrlUpdateLog);
	setHistoryLogURL(strUrlHistoryLog);

	// Create a session manager
	//-------------------------
	try {
		_sessionManager = new UMSessionManager(new URL(_strUpdateLogURL), new URL(_strHistoryLogURL), true);
	}
	catch (MalformedURLException ex) {
		throw new UpdateManagerException("Invalid log URL specification");
	}
	catch (LogStoreException ex) {
		throw new UpdateManagerException(ex.getMessage());
	}

	// Registry Manager
	//-----------------
	_registryManager = new UMRegistryManager(urlBase);
}
/**
 * 
 */
public void removeComponent(IComponentDescriptor componentDescriptor) {
	removeComponent(componentDescriptor, null);
}
/**
 * 
 */
public void removeComponent(IComponentDescriptor componentDescriptor, IProductDescriptor productDescriptor) {

	if( componentDescriptor == null )
		return;
		
	LaunchInfo launchInfo = LaunchInfo.getCurrent();
	LaunchInfo.VersionedIdentifier vid = null;

	// Plugins
	//--------
	IPluginEntryDescriptor[] pluginEntries = componentDescriptor.getPluginEntries();

	for (int i = 0; i < pluginEntries.length; ++i) {
		vid = new LaunchInfo.VersionedIdentifier(pluginEntries[i].getUniqueIdentifier(), pluginEntries[i].getVersionStr());
		launchInfo.removePlugin(vid);
	}

	// Fragments
	//----------
	IFragmentEntryDescriptor[] fragmentEntries = componentDescriptor.getFragmentEntries();

	for (int i = 0; i < fragmentEntries.length; ++i) {
		vid = new LaunchInfo.VersionedIdentifier(fragmentEntries[i].getUniqueIdentifier(), pluginEntries[i].getVersionStr());
		launchInfo.removeFragment(vid);
	}

	// Component
	//----------
	vid = new LaunchInfo.VersionedIdentifier(componentDescriptor.getUniqueIdentifier(), componentDescriptor.getVersionStr());
	launchInfo.removeComponent(vid);
	_registryManager.removeComponentDescriptorFromLocal(componentDescriptor, productDescriptor);
	
	return;
}
/**
 * 
 */
public void removeProduct(IProductDescriptor productDescriptor) {

	if( productDescriptor == null )
		return;
		
	// Components
	//-----------
	IComponentEntryDescriptor[] componentEntries = productDescriptor.getComponentEntries();

	for (int i = 0; i < componentEntries.length; ++i) {
		IComponentDescriptor componentDescriptor = componentEntries[i].getComponentDescriptor();
		if (componentDescriptor.isRemovable(productDescriptor))
			removeComponent(componentDescriptor, productDescriptor);
	}

	// Product
	//--------
	LaunchInfo.VersionedIdentifier vid = new LaunchInfo.VersionedIdentifier(productDescriptor.getUniqueIdentifier(), productDescriptor.getVersionStr());
	LaunchInfo.getCurrent().removeConfiguration(vid);
	_registryManager.removeProductDescriptorFromLocal(productDescriptor);
}
/**
 * Sets the URL for the history log.  This property is persistent.
 */
public void setHistoryLogURL(String strURL) throws UpdateManagerException {

	// Check for valid URL
	//--------------------
	try {
		new URL(strURL);
	}
	catch (MalformedURLException ex) {
		throw new UpdateManagerException("Invalid log URL specification");
	}

	// Change the property
	//--------------------
	_strHistoryLogURL = strURL;
}
/**
 * Sets the URL for the update log.  This property is persistent.
 */
public void setUpdateLogURL(String strURL) throws UpdateManagerException {
	
	// Check for valid URL
	//--------------------
	try {
		new URL(strURL);
	}
	catch (MalformedURLException ex) {
		throw new UpdateManagerException("Invalid log URL specification");
	}

	// Change the property
	//--------------------
	_strUpdateLogURL = strURL;
}
/**
 * Updates the boot loader's launch information with what is currently installed.
 */
public void updateLaunchInfoAndRegistry(UMSessionManagerSession session) {

	// Update launch info even if this session had a failure
	// One or more parcels could have succeeded
	//------------------------------------------------------
	if (session != null) {
		
		LaunchInfo launchInfo = LaunchInfo.getCurrent();

		// Obtain product/component information
		//-------------------------------------
		UMSessionManagerParcel[] parcels = session.getParcels();

		for (int i = 0; i < parcels.length; ++i) {
			updateLaunchInfoAndRegistryParcel( parcels[i], launchInfo );
		}
	}
}
/**
 * Recursively updates the boot loader's information for this parcel and sub-parcels.
 */
protected void updateLaunchInfoAndRegistryParcel(UMSessionManagerParcel parcel, LaunchInfo launchInfo) {

	// Update the profile only if the install was successful
	//------------------------------------------------------
	if (parcel != null && parcel.getStatus().equals(UpdateManagerConstants.STATUS_SUCCEEDED) == true) {

		Object objData = parcel.getData();

		// Product
		//--------
		if (objData instanceof IProductDescriptor) {
			updateLaunchInfoProduct((IProductDescriptor) objData, launchInfo);
			_registryManager.addProductDescriptorToLocal((IProductDescriptor) objData);
		}

		// Component
		//----------
		else if (objData instanceof IComponentDescriptor) {
			updateLaunchInfoComponent((IComponentDescriptor) objData, launchInfo);
			_registryManager.addComponentDescriptorToLocal((IComponentDescriptor) objData, true);
		}
			
		// Component Entry
		//----------------
		else if (objData instanceof IComponentEntryDescriptor) {
			IComponentDescriptor comp = ((IComponentEntryDescriptor)objData).getComponentDescriptor();
			updateLaunchInfoComponent(comp, launchInfo);
			_registryManager.addComponentDescriptorToLocal(comp, false);
		}

		// Do child parcels
		//-----------------
		UMSessionManagerParcel[] parcelChildren = parcel.getParcels();

		for (int i = 0; i < parcelChildren.length; ++i) {
			updateLaunchInfoAndRegistryParcel(parcelChildren[i], launchInfo);
		}
	}
}
/**
 * Updates the boot loader's launch information with what is currently installed.
 */
public void updateLaunchInfoComponent(IComponentDescriptor descriptor, LaunchInfo launchInfo) {

	// Component
	//----------
	launchInfo.setComponent(new LaunchInfo.VersionedIdentifier(descriptor.getUniqueIdentifier(), descriptor.getVersionStr()));

	// Plugins
	//--------
	IPluginEntryDescriptor[] pluginDescriptors = descriptor.getPluginEntries();

	for (int i = 0; i < pluginDescriptors.length; ++i) {
		updateLaunchInfoPlugin(pluginDescriptors[i], launchInfo);
	}

	// Fragments
	//----------
	IFragmentEntryDescriptor[] fragmentDescriptors = descriptor.getFragmentEntries();

	for (int i = 0; i < fragmentDescriptors.length; ++i) {
		updateLaunchInfoFragment(fragmentDescriptors[i], launchInfo);
	}
}
/**
 * Updates the boot loader's launch information with what is currently installed.
 */
public void updateLaunchInfoFragment(IFragmentEntryDescriptor descriptor, LaunchInfo launchInfo) {

	launchInfo.setFragment(new LaunchInfo.VersionedIdentifier(descriptor.getUniqueIdentifier(),descriptor.getVersionStr()));
}
/**
 * Updates the boot loader's launch information with what is currently installed.
 */
public void updateLaunchInfoPlugin(IPluginEntryDescriptor descriptor, LaunchInfo launchInfo) {

	launchInfo.setPlugin(new LaunchInfo.VersionedIdentifier(descriptor.getUniqueIdentifier(),descriptor.getVersionStr()));
}
/**
 * Updates the boot loader's launch information with what is currently installed.
 */
public void updateLaunchInfoProduct(IProductDescriptor descriptor, LaunchInfo launchInfo) {

	launchInfo.setConfiguration(new LaunchInfo.VersionedIdentifier(descriptor.getUniqueIdentifier(),descriptor.getVersionStr()), descriptor.getApplication());
}
}
