/*******************************************************************************
 * 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.internal.core;
import java.io.*;
import java.net.*;
import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.update.core.*;
import org.eclipse.update.core.model.*;

/**
 * ContentConsummer for a SiteFile
 */
public class SiteFileContentConsumer extends SiteContentConsumer {

	private IFeature feature;
	private boolean closed = false;

	// recovery
	private String oldPath;
	private String newPath;

	//  for abort
	private List /* of SiteFilePluginContentConsumer */
	contentConsumers;
	private List /*of path as String */
	installedFiles;
	
	// PERF: new instance variable
	private SiteFileFactory archiveFactory = new SiteFileFactory();

	/*
	 * Constructor 
	 */
	public SiteFileContentConsumer(IFeature feature) {
		this.feature = feature;
		installedFiles = new ArrayList();
	}

	/*
	 * Returns the path in which the Feature will be installed
	 */
	private String getFeaturePath() throws CoreException {
		String featurePath = null;
		try {
			VersionedIdentifier featureIdentifier = feature.getVersionedIdentifier();
			String path = Site.DEFAULT_INSTALLED_FEATURE_PATH + featureIdentifier.toString() + File.separator;
			URL newURL = new URL(getSite().getURL(), path);
			featurePath = newURL.getFile();
		} catch (MalformedURLException e) {
			throw Utilities.newCoreException(Policy.bind("SiteFileContentConsumer.UnableToCreateURL") + e.getMessage(), e);	//$NON-NLS-1$
		}
		return featurePath;
	}

	/*
	 * @see ISiteContentConsumer#open(INonPluginEntry)
	 */
	public IContentConsumer open(INonPluginEntry nonPluginEntry) throws CoreException {
		return new SiteFileNonPluginContentConsumer(getFeaturePath());
	}

	/*
	 * @see ISiteContentConsumer#open(IPluginEntry)
	 */
	public IContentConsumer open(IPluginEntry pluginEntry) throws CoreException {
		ContentConsumer cons;
		if(pluginEntry instanceof PluginEntryModel && !((PluginEntryModel)pluginEntry).isUnpack()){
			// plugin can run from a jar
			 cons = new SiteFilePackedPluginContentConsumer(pluginEntry, getSite());
		} else{
			// plugin must be unpacked
			cons = new SiteFilePluginContentConsumer(pluginEntry, getSite());
		}
		addContentConsumers(cons);
		return cons;
	}

	/*
	 * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
	 */
	public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {

		if (closed) {
			UpdateCore.warn("Attempt to store in a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$
			return;
		}

		InputStream inStream = null;
		String featurePath = getFeaturePath();
		String contentKey = contentReference.getIdentifier();
		featurePath += contentKey;

		// error recovery
		if (featurePath.endsWith("\\"+Feature.FEATURE_XML) || featurePath.endsWith("/"+Feature.FEATURE_XML)) { //$NON-NLS-1$ //$NON-NLS-2$
			oldPath = featurePath.replace(File.separatorChar, '/');
			File localFile = new File(oldPath);
			if (localFile.exists()) {
				throw Utilities.newCoreException(Policy.bind("UpdateManagerUtils.FileAlreadyExists", new Object[] { localFile }), null); //$NON-NLS-1$
			}
			featurePath = ErrorRecoveryLog.getLocalRandomIdentifier(featurePath);
			newPath = featurePath;
			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.FEATURE_ENTRY, featurePath);
		}

		try {
			inStream = contentReference.getInputStream();
			UpdateManagerUtils.copyToLocal(inStream, featurePath, null);
			UpdateManagerUtils.checkPermissions(contentReference, featurePath); // 20305
			installedFiles.add(featurePath);
		} catch (IOException e) {
			throw Utilities.newCoreException(Policy.bind("GlobalConsumer.ErrorCreatingFile", featurePath), e); //$NON-NLS-1$
		} finally {
			if (inStream != null) {
				try {
					// close stream
					inStream.close();
				} catch (IOException e) {
				}
			}
		}

	}

	/*
	 * @see ISiteContentConsumer#close()
	 */
	public IFeatureReference close() throws CoreException {

		if (closed)
			UpdateCore.warn("Attempt to close a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$

		// create a new Feature reference to be added to the site
		SiteFeatureReference ref = new SiteFeatureReference();
		ref.setSite(getSite());
		File file = null;

		try {
			file = new File(getFeaturePath());
			ref.setURL(file.toURL());
		} catch (MalformedURLException e) {
			throw Utilities.newCoreException(Policy.bind("SiteFileContentConsumer.UnableToCreateURLForFile", file.getAbsolutePath()), e); //$NON-NLS-1$
		}

		//rename file back 
		if (newPath != null) {
			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.RENAME_ENTRY, newPath);
			boolean sucess = false;
			File fileToRename = new File(newPath);
			if (fileToRename.exists()) {
				File renamedFile = new File(oldPath);
				if (renamedFile.exists()) {
					UpdateManagerUtils.removeFromFileSystem(renamedFile);
					UpdateCore.warn("Removing already existing file:" + oldPath); //$NON-NLS-1$
				}
				sucess = fileToRename.renameTo(renamedFile);
			}
			if (!sucess) {
				String msg = Policy.bind("ContentConsumer.UnableToRename", newPath, oldPath); //$NON-NLS-1$
				throw Utilities.newCoreException(msg, new Exception(msg));
			}
		}

		// close plugin and non plugin content consumer
		if (contentConsumers != null) {
			Iterator iter = contentConsumers.iterator();
			while (iter.hasNext()) {
				ContentConsumer element = (ContentConsumer) iter.next();
				element.close();
			}
		}
		contentConsumers = null;

		if (ref != null) {
			// the feature MUST have renamed the plugins at that point
			// (by closing the PluginContentConsumer)
			commitPlugins(ref);
			ref.markReadOnly();
		}

		closed = true;
		return ref;
	}

	/*
	 * @see ISiteContentConsumer#abort()
	 */
	public void abort() throws CoreException {

		if (closed) {
			UpdateCore.warn("Attempt to abort a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$
			return;
		}

		//abort all plugins content consumer opened
		if (contentConsumers != null) {
			Iterator iter = contentConsumers.iterator();
			while (iter.hasNext()) {
				SiteFilePluginContentConsumer element = (SiteFilePluginContentConsumer) iter.next();
				element.abort();
			}
		}
		contentConsumers = null;
		boolean sucess = true;

		//Remove feature.xml first if it exists
		if (oldPath != null) {
			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.DELETE_ENTRY, oldPath);
			File fileToDelete = new File(oldPath);
			if (fileToDelete.exists()) {
				sucess = fileToDelete.delete();
			}
		}

		if (!sucess) {
			String msg = Policy.bind("Unable to delete", oldPath); //$NON-NLS-1$
			UpdateCore.log(msg, null);
		} else {
			// remove the feature files;
			Iterator iter = installedFiles.iterator();
			File featureFile = null;
			while (iter.hasNext()) {
				String path = (String) iter.next();
				featureFile = new File(path);
				UpdateManagerUtils.removeFromFileSystem(featureFile);
			}

			// remove the feature directory if empty
			String featurePath = getFeaturePath();
			UpdateManagerUtils.removeEmptyDirectoriesFromFileSystem(new File(featurePath));
		}
		closed = true;
		return;
	}

	/*
	 * commit the plugins installed as archive on the site
	 * (creates the map between the plugin id and the location of the plugin)
	 */
	private void commitPlugins(IFeatureReference localFeatureReference) throws CoreException {
	
		// get the feature
		 ((SiteFile) getSite()).addFeatureReferenceModel((SiteFeatureReferenceModel) localFeatureReference);
		IFeature localFeature = null;
		try {
			localFeature = localFeatureReference.getFeature(null);
		} catch (CoreException e) {
			UpdateCore.warn(null, e);
			return;
		}
	
		if (localFeature == null)
			return;
	
		// add the installed plugins directories as archives entry
		ArchiveReferenceModel archive = null;
		IPluginEntry[] pluginEntries = localFeature.getPluginEntries();
		for (int i = 0; i < pluginEntries.length; i++) {
			String versionId = pluginEntries[i].getVersionedIdentifier().toString();
			String pluginID = Site.DEFAULT_PLUGIN_PATH + versionId + FeaturePackagedContentProvider.JAR_EXTENSION;
			archive = archiveFactory.createArchiveReferenceModel();
			archive.setPath(pluginID);
			try {
				URL url = new URL(getSite().getURL(), Site.DEFAULT_PLUGIN_PATH + versionId + File.separator);
				archive.setURLString(url.toExternalForm());
				archive.resolve(url, null);
				((SiteFile) getSite()).addArchiveReferenceModel(archive);
			} catch (MalformedURLException e) {
	
				String urlString = (getSite().getURL() != null) ? getSite().getURL().toExternalForm() : "";	//$NON-NLS-1$
				urlString += Site.DEFAULT_PLUGIN_PATH + pluginEntries[i].toString();
				throw Utilities.newCoreException(Policy.bind("SiteFile.UnableToCreateURL", urlString), e);	//$NON-NLS-1$
			}
		}
		return;
	}

	/*
	 * Adds a SiteFilePluginContentConsumer to the list
	 */
	private void addContentConsumers(ContentConsumer cons) {
		if (contentConsumers == null)
			contentConsumers = new ArrayList();
		contentConsumers.add(cons);
	}

}
