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

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.core.*;
import org.eclipse.update.configurator.*;


/**
 * singleton pattern.
 * manages the error/recover log file
 */
public class ErrorRecoveryLog {

	public static final boolean RECOVERY_ON = false;

	private static final String ERROR_RECOVERY_LOG = "error_recovery.log"; //$NON-NLS-1$
	private static final String LOG_ENTRY_KEY = "LogEntry."; //$NON-NLS-1$
	private static final String RETURN_CARRIAGE = "\r\n"; //$NON-NLS-1$
	private static final String END_OF_FILE = "eof=eof"; //$NON-NLS-1$

	//
	public static final String START_INSTALL_LOG = 	"START_INSTALL_LOG"; //$NON-NLS-1$
	public static final String PLUGIN_ENTRY = 		"PLUGIN"; //$NON-NLS-1$
	public static final String FRAGMENT_ENTRY = 		"FRAGMENT";	 //$NON-NLS-1$
	public static final String BUNDLE_MANIFEST_ENTRY = 		"BUNDLE_MANIFEST";	 //$NON-NLS-1$
	public static final String BUNDLE_JAR_ENTRY = 			"BUNDLE";	 //$NON-NLS-1$
	public static final String FEATURE_ENTRY = 		"FEATURE"; //$NON-NLS-1$
	public static final String ALL_INSTALLED = 		"ALL_FEATURES_INSTALLED"; //$NON-NLS-1$
	public static final String RENAME_ENTRY = 		"RENAME"; //$NON-NLS-1$
	public static final String END_INSTALL_LOG = 	"END_INSTALL_LOG"; //$NON-NLS-1$
	public static final String START_REMOVE_LOG = 	"REMOVE_LOG"; //$NON-NLS-1$
	public static final String END_ABOUT_REMOVE =	"END_ABOUT_TO_REMOVE"; //$NON-NLS-1$
	public static final String DELETE_ENTRY = 		"DELETE"; //$NON-NLS-1$
	public static final String END_REMOVE_LOG = 		"END_REMOVE_LOG"; //$NON-NLS-1$

	public static boolean forceRemove = false;

	private static ErrorRecoveryLog inst;
	private FileWriter out;
	private int index;
	private List paths;
	
	private boolean open = false;
	private int nbOfOpen = 0;
	

	/**
	 * Constructor for ErrorRecoveryLog.
	 */
	private ErrorRecoveryLog() {
		super();
	}

	/**
	 * Singleton
	 */
	public static ErrorRecoveryLog getLog() {
		if (inst == null){
			inst = new ErrorRecoveryLog();
		}
		return inst;
	}

	/**
	 * get a unique identifer for the file, ensure uniqueness up to now
	 */
	public static String getLocalRandomIdentifier(String path) {
		
		if (path==null) return null;
		
		// verify if it will be a directory without creating the file
		// as it doesn't exist yet
		if (path.endsWith(File.separator) || path.endsWith("/")) //$NON-NLS-1$
			return path;
		File file = new File(path);
		String newName =
			UpdateManagerUtils.getLocalRandomIdentifier(file.getName(), new Date());
		while (new File(newName).exists()) {
			newName =
				UpdateManagerUtils.getLocalRandomIdentifier(file.getName(), new Date());
		}
		File newFile = new File(file.getParentFile(),newName);
		return newFile.getAbsolutePath();
	}

	/**
	 * returns the log file 
	 * We do not check if the file exists
	 */
	public File getRecoveryLogFile() {
		IPlatformConfiguration configuration =
			ConfiguratorUtils.getCurrentPlatformConfiguration();
		URL location = configuration.getConfigurationLocation();
		String locationString = location.getFile();
		File platformConfiguration = new File(locationString);
		if (!platformConfiguration.isDirectory()) platformConfiguration = platformConfiguration.getParentFile();
		return new File(platformConfiguration, ERROR_RECOVERY_LOG);
	}


	/**
	 * Open the log
	 */
	public void open(String logEntry) throws CoreException {
		if (open) {
			nbOfOpen++;			
			UpdateCore.warn("Open nested Error/Recovery log #"+nbOfOpen+":"+logEntry);				 //$NON-NLS-1$ //$NON-NLS-2$
			return;
		}
		
		File logFile = null;		
		try {
			logFile = getRecoveryLogFile();
			out = new FileWriter(logFile);
			index = 0;
			paths=null;
			open=true;
			nbOfOpen=0;
			UpdateCore.warn("Start new Error/Recovery log #"+nbOfOpen+":"+logEntry);							 //$NON-NLS-1$ //$NON-NLS-2$
		} catch (IOException e) {
			throw Utilities.newCoreException(
				NLS.bind(Messages.UpdateManagerUtils_UnableToLog, (new Object[] { logFile })),
				e);
		}
		
		append(logEntry);
	}

	/**
	 * Append the string to the log and flush
	 */
	public void append(String logEntry) throws CoreException {
		File logFile = null;
		try {
			if (!open) {
				UpdateCore.warn("Internal Error: The Error/Recovery log is not open:"+logEntry);				 //$NON-NLS-1$
				return;
			}

			StringBuffer buffer = new StringBuffer(LOG_ENTRY_KEY);
			buffer.append(index);
			buffer.append("="); //$NON-NLS-1$
			buffer.append(logEntry);
			buffer.append(RETURN_CARRIAGE);

			out.write(buffer.toString());
			out.flush();
			index++;
		} catch (IOException e) {
			throw Utilities.newCoreException(
				NLS.bind(Messages.UpdateManagerUtils_UnableToLog, (new Object[] { logFile })),
				e);
		}
	}

	/**
	 * Append the string to the log and flush
	 */
	public void appendPath(String logEntry, String path) throws CoreException {
		if (path == null)
			return;
		StringBuffer buffer = new StringBuffer(logEntry);
		buffer.append(" "); //$NON-NLS-1$
		buffer.append(path);
		append(buffer.toString());
		
		addPath(path);
	}

	/**
	 * Close any open recovery log
	 */
	public void close(String logEntry) throws CoreException {
		
		if (nbOfOpen>0){
			UpdateCore.warn("Close nested Error/Recovery log #"+nbOfOpen+":"+logEntry);			 //$NON-NLS-1$ //$NON-NLS-2$
			nbOfOpen--;			
			return;
		}			
		
		UpdateCore.warn("Close Error/Recovery log #"+nbOfOpen+":"+logEntry); //$NON-NLS-1$ //$NON-NLS-2$
		append(logEntry);
		if (out != null) {
			try {
				out.write(END_OF_FILE);
				out.flush();
				out.close();
			} catch (IOException e) { //eat the exception
			} finally {
				out = null;
				open=false;
			}
		}
	}

	/**
	 * Delete the file from the file system
	 */
	public void delete() {
		//File logFile = getRecoveryLogFile();
		getRecoveryLogFile();
		//if (logFile.exists())
			//logFile.delete();	
	}

	/**
	 * 
	 */
	private void addPath(String path){
		if (paths==null) paths = new ArrayList();
		paths.add(path);
	}
	
	/** 
	 * recover an install or remove that didn't finish
	 * Delete file for an unfinished delete
	 * Delete file for an unfinshed install if not all the files were installed
	 * Rename XML files for an install if all the files were installed but not renamed
	 */
	public IStatus recover(){
		
		IStatus mainStatus = createStatus(IStatus.OK,Messages.ErrorRecoveryLog_recoveringStatus,null); 
		MultiStatus multi = new MultiStatus(mainStatus.getPlugin(),mainStatus.getCode(),mainStatus.getMessage(),null);

		//check if recovery is on
		if (!RECOVERY_ON){
			UpdateCore.warn("Recovering is turned off. Abort recovery"); //$NON-NLS-1$
			return multi;
		}
		
		File logFile = getRecoveryLogFile();
		if (!logFile.exists()){
			multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_cannotFindLogFile+logFile,null)); 
			return multi;
		}
		
		InputStream in = null;
		Properties prop = null;
		try {
			in = new FileInputStream(logFile);
			prop = new Properties();
			prop.load(in);
		} catch (IOException e){
			UpdateCore.warn("Unable to read:"+logFile,e); //$NON-NLS-1$
			multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_noPropertyFile+logFile,e)); 
			return multi;
		} finally {
			if (in != null)
				try {
					in.close();
				} catch (IOException e1) {
				}
		}
		
		String eof = prop.getProperty("eof"); //$NON-NLS-1$
		if(eof!=null && eof.equals("eof")){ //$NON-NLS-1$
			// all is good
			delete();
			UpdateCore.warn("Found log file. Log file contains end-of-file. No need to process"); //$NON-NLS-1$
			multi.add(createStatus(IStatus.OK,null,null));
			return multi;
		}
		
		String recovery = prop.getProperty(LOG_ENTRY_KEY+"0"); //$NON-NLS-1$
		if (recovery==null){
			multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_noLogEntry+logFile,null)); 
			return multi;			
		}
	
		if(recovery.equalsIgnoreCase(START_INSTALL_LOG)){
			multi.addAll(processRecoverInstall(prop));
			return multi;
		}
		
		if(recovery.equalsIgnoreCase(START_REMOVE_LOG)){
			multi.addAll(processRecoverRemove(prop));
			return multi;
		}

		multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_noRecoveryToExecute+logFile,null)); 
		return multi;	
	}
	
	/*
	 * creates a Status
	 */
	private IStatus createStatus(int statusSeverity, String msg, Exception e){
		String id =
			UpdateCore.getPlugin().getBundle().getSymbolicName();
	
		StringBuffer completeString = new StringBuffer(""); //$NON-NLS-1$
		if (msg!=null)
			completeString.append(msg);
		if (e!=null){
			completeString.append("\r\n["); //$NON-NLS-1$
			completeString.append(e.toString());
			completeString.append("]\r\n"); //$NON-NLS-1$
		}
		return new Status(statusSeverity, id, IStatus.OK, completeString.toString(), e);
	}	
	
	/*
	 * 
	 */
	 private IStatus processRecoverInstall(Properties prop){
	 	
		IStatus mainStatus = createStatus(IStatus.OK,"",null); //$NON-NLS-1$
		MultiStatus multi = new MultiStatus(mainStatus.getPlugin(),mainStatus.getCode(),"",null); //$NON-NLS-1$
	 	
	 	Collection values = prop.values();
	 	
	 	if(values.contains(END_INSTALL_LOG)){
			// all is good
			delete();
			UpdateCore.warn("Found log file. Log file contains END_INSTALL_LOG. No need to process rename"); //$NON-NLS-1$
			multi.add(createStatus(IStatus.OK,null,null));
			return multi;
	 	}
	 	
	 	if (values.contains(ALL_INSTALLED) && !forceRemove){
	 		// finish install by renaming
	 		int index = 0;
	 		boolean found = false;
	 		String val = prop.getProperty(LOG_ENTRY_KEY+index);
	 		while(val!=null && !found){
	 			if(val.equalsIgnoreCase(ALL_INSTALLED)) found = true;
	 			IStatus renameStatus = processRename(val);
	 			UpdateCore.log(renameStatus);
	 			if(renameStatus.getSeverity()!=IStatus.OK){
	 				multi.add(renameStatus);
	 			}
	 			index++;
	 			val = prop.getProperty(LOG_ENTRY_KEY+index);	 			
	 		}
	 		if (val==null){
	 			UpdateCore.warn("Unable to find value for :"+LOG_ENTRY_KEY+index); //$NON-NLS-1$
	 			multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_wrongLogFile+LOG_ENTRY_KEY+index,null)); 
				return multi;
	 		}
	 		// process recovery finished
	 		delete();
			UpdateCore.warn("Found log file. Successfully recovered by renaming. Feature is installed."); //$NON-NLS-1$
			multi.add(createStatus(IStatus.OK,null,null));
	 	} else {
	 		// remove all because install did not lay out all the files
	 		// or recovery is not allowed
	 		int index = 0;
	 		String val = prop.getProperty(LOG_ENTRY_KEY+index);
	 		while(val!=null){
	 			IStatus removeStatus = processRemove(val);
	 			UpdateCore.log(removeStatus);
	 			if(removeStatus.getSeverity()!=IStatus.OK){
	 				multi.addAll(removeStatus);
	 			}
	 			index++;
	 			val = prop.getProperty(LOG_ENTRY_KEY+index);	 			
	 		}
	 		// process recovery finished
	 		delete();
			UpdateCore.warn("Found log file. Successfully recovered by removing. Feature is removed."); //$NON-NLS-1$
			multi.add(createStatus(IStatus.OK,null,null));
	 	}
	 	return multi;
	 }
	 
	 /*
	  * 
	  */
	  private IStatus processRename(String val){
	  	
		// get the path
		int index = -1;
		String newFileName = null;
	  	if (val.startsWith(PLUGIN_ENTRY)){
	  		index = PLUGIN_ENTRY.length();
	  		newFileName= "plugin.xml"; //$NON-NLS-1$
	  	} else if (val.startsWith(BUNDLE_MANIFEST_ENTRY)){
	  		index = BUNDLE_MANIFEST_ENTRY.length();
	  		newFileName= "META-INF/MANIFEST.MF"; //$NON-NLS-1$
	  	}else if (val.startsWith(FRAGMENT_ENTRY)){
	  		index = FRAGMENT_ENTRY.length();
	  		newFileName= "fragment.xml"; //$NON-NLS-1$
	  	} else if (val.startsWith(FEATURE_ENTRY)){
	  		index = FEATURE_ENTRY.length();
	  		newFileName= "feature.xml"; //$NON-NLS-1$
	  	} else if (val.startsWith(BUNDLE_JAR_ENTRY)){
	  		index = BUNDLE_JAR_ENTRY.length();
	  	}
	  	
	  	if (index==-1){
	  		return createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_noAction+val,null); 
	  	}
	  	
	  	String oldName = val.substring(index+1);
	  	// oldname is com.pid/plugin#####.xml
	  	// or oldname is com.pid/pid_pver.jar######.tmp
	  	File oldFile = new File(oldName);
	  	File newFile;
	  	if(val.startsWith(BUNDLE_JAR_ENTRY)){
	  		newFile = new File(oldFile.getAbsolutePath().substring(0, oldFile.getAbsolutePath().lastIndexOf(".jar")+".jar".length())); //$NON-NLS-1$ //$NON-NLS-2$
	  	}else{
	  		newFile = new File(oldFile.getParentFile(),newFileName);
	  	}
	  	if (!oldFile.exists()){
	  		if (newFile.exists()){
	  			// ok the file has been renamed apparently
			  	return createStatus(IStatus.OK,Messages.ErrorRecoveryLog_fileAlreadyRenamed+newFile,null);	  				 
	  		} else {
	  			// the file doesn't exist, log as problem, and force the removal of the feature
		  		return createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_cannotFindFile+oldFile,null);	  			 
	  		}
	  	} 	
	  	
		boolean sucess = false;
		if (newFile.exists()) {
			UpdateManagerUtils.removeFromFileSystem(newFile);
			UpdateCore.warn("Removing already existing file:"+newFile); //$NON-NLS-1$
		}
		sucess = oldFile.renameTo(newFile);
			
		if(!sucess){
			String msg =(Messages.ErrorRecoveryLog_oldToNew+oldFile+newFile); 
			return createStatus(IStatus.ERROR,msg,null);
		}
		return createStatus(IStatus.OK,Messages.ErrorRecoveryLog_renamed+oldFile+Messages.ErrorRecoveryLog_to+newFile,null); 
	  }
	  
	 /*
	  * 
	  */
	  private IStatus processRemove(String val){
	  	
		IStatus mainStatus = createStatus(IStatus.OK,"",null); //$NON-NLS-1$
		MultiStatus multi = new MultiStatus(mainStatus.getPlugin(),mainStatus.getCode(),"",null);	  	 //$NON-NLS-1$
	  	
		// get the path
		int index = -1;
		if (val.startsWith(BUNDLE_JAR_ENTRY)){
	  		index = BUNDLE_JAR_ENTRY.length();
	  	}
	  	
	  	if (index==-1){
	  		return createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_noAction+val,null); 
	  	}
	  	
	  	String oldName = val.substring(index+1);
	  	File oldFile = new File(oldName);
	  	if (!oldFile.exists()){
  			// the jar or directory doesn't exist, log as problem, and force the removal of the feature
	  		multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_cannotFindFile+oldFile,null));	  			 
	  		return multi;
	  	} 		  	
		multi.addAll(removeFromFileSystem(oldFile));

		return multi;
	  }	
	  
	/**
	 * return a multi status, 
	 * the children are the file that couldn't be removed
	 */
	public IStatus removeFromFileSystem(File file) {
		
		IStatus mainStatus = createStatus(IStatus.OK,"",null); //$NON-NLS-1$
		MultiStatus multi = new MultiStatus(mainStatus.getPlugin(),mainStatus.getCode(),"",null);		 //$NON-NLS-1$
		
		if (!file.exists()){
			multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_noFiletoRemove+file,null)); 
			return multi;
		}
			
		if (file.isDirectory()) {
			String[] files = file.list();
			if (files != null) // be careful since file.list() can return null
				for (int i = 0; i < files.length; ++i){
					multi.addAll(removeFromFileSystem(new File(file, files[i])));
				}
		}
		
		if (!file.delete()) {
			String msg = "Unable to remove file" +file.getAbsolutePath(); //$NON-NLS-1$ 
			multi.add(createStatus(IStatus.ERROR,msg,null));
		}
		return multi;
	}	
	
	/*
	 * 
	 */
	 private IStatus processRecoverRemove(Properties prop){
	 	
		IStatus mainStatus = createStatus(IStatus.OK,"",null); //$NON-NLS-1$
		MultiStatus multi = new MultiStatus(mainStatus.getPlugin(),mainStatus.getCode(),"",null); //$NON-NLS-1$
	 	
	 	Collection values = prop.values();
	 	
	 	if(values.contains(END_REMOVE_LOG)){
			// all is good
			delete();
			UpdateCore.warn("Found log file. Log file contains END_REMOVE_LOG. No need to process rename"); //$NON-NLS-1$
			multi.add(createStatus(IStatus.OK,null,null));
			return multi;
	 	}
	 	
	 	if (!values.contains(END_ABOUT_REMOVE)){
	 		// finish install by renaming
 			multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_removeFeature,null)); 
				return multi;
	 	} else {
	 		// finish install by renaming
	 		int index = 0;
	 		boolean found = false;
	 		String val = prop.getProperty(LOG_ENTRY_KEY+index);
	 		while(val!=null && !found){
	 			if(val.equalsIgnoreCase(END_ABOUT_REMOVE)) found = true;
	 			IStatus renameStatus = processRemove(val);
	 			UpdateCore.log(renameStatus);
	 			if(renameStatus.getSeverity()!=IStatus.OK){
	 				multi.add(renameStatus);
	 			}
	 			index++;
	 			val = prop.getProperty(LOG_ENTRY_KEY+index);	 			
	 		}
	 		if (val==null){
	 			UpdateCore.warn("Unable to find value for :"+LOG_ENTRY_KEY+index); //$NON-NLS-1$
	 			multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_wrongLogFile+LOG_ENTRY_KEY+index,null)); 
				return multi;
	 		}
	 		// process recovery finished
	 		delete();
			UpdateCore.warn("Found log file. Successfully recovered by deleting. Feature is removed."); //$NON-NLS-1$
			multi.add(createStatus(IStatus.OK,null,null));
	 	}
	 	return multi;
	 }	    
}
