/*******************************************************************************
 * Copyright (c) 2000, 2003 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.configuration.*;
import org.eclipse.update.configurator.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.operations.*;


/**
 * Parses the installation log and creates installation configuration objects
 */
public class InstallLogParser {
	private IPath logPath;
	private BufferedReader buffRead;
	private InstallConfiguration currentConfiguration;
	private HashMap installConfigMap;
	private Comparator comparator;
	
	private static final String FEATURE_INSTALL = "feature-install"; //$NON-NLS-1$
	private static final String FEATURE_REMOVE = "feature-remove"; //$NON-NLS-1$
	private static final String SITE_INSTALL = "site-install"; //$NON-NLS-1$
	private static final String SITE_REMOVE = "site-remove"; //$NON-NLS-1$
	private static final String UNCONFIGURE = "feature-disable"; //$NON-NLS-1$
	private static final String CONFIGURE = "feature-enable"; //$NON-NLS-1$
	private static final String REVERT = "revert"; //$NON-NLS-1$
	private static final String RECONCILIATION = "reconciliation"; //$NON-NLS-1$
	private static final String PRESERVED = "preserve-configuration"; //$NON-NLS-1$	
	
	private static final String ACTIVITY = "!ACTIVITY"; //$NON-NLS-1$
	
	public static final String SUCCESS = "success"; //$NON-NLS-1$
	public static final String FAILURE = "failure"; //$NON-NLS-1$

	
	public InstallLogParser(){
		String loc = ConfiguratorUtils.getCurrentPlatformConfiguration().getConfigurationLocation().getFile();
		logPath = new Path(loc).removeLastSegments(1).append("install.log");  //$NON-NLS-1$
		installConfigMap = new HashMap();
		try {
			InstallConfiguration[] configs = (InstallConfiguration[])SiteManager.getLocalSite().getConfigurationHistory();
			for (int i=0;i<configs.length; i++){
				if (!configs[i].isCurrent())
					installConfigMap.put(new Long(configs[i].getCreationDate().getTime()), configs[i]);
			}
			// Need to make a copy of the current config instead
			InstallConfiguration config = getConfigCopy((InstallConfiguration)SiteManager.getLocalSite().getCurrentConfiguration());
			installConfigMap.put(new Long(config.getCreationDate().getTime()), config);
			
		} catch (CoreException e) {
			UpdateCore.log(e);
		} catch (MalformedURLException e){
			UpdateCore.log(e);
		}
		comparator = new Comparator(){
			public int compare(Object e1, Object e2) {
				Date date1 = ((InstallConfiguration)e1).getCreationDate();
				Date date2 = ((InstallConfiguration)e2).getCreationDate();
				return date1.before(date2) ? 1 : -1;
			}
		};
	}
	private InstallConfiguration getConfigCopy(InstallConfiguration origConfig) throws CoreException, MalformedURLException{
		InstallConfiguration config = new InstallConfiguration(origConfig, origConfig.getURL(), origConfig.getLabel() );
		config.setCreationDate(origConfig.getCreationDate());
		return config;
	}
	public void parseInstallationLog(){
		try {
			openLog();
			parseLog();
		} catch (CoreException e) {
			UpdateUtils.logException(e);
		} finally {
			closeLog();
		}
	}
	
	private void openLog() throws CoreException {
		try {
			buffRead = new BufferedReader(new FileReader(logPath.toOSString()));
		} catch (FileNotFoundException e) {
			throwCoreException(e);
		}
	}
	
	private void throwCoreException(Throwable e) throws CoreException {
		throw new CoreException(
			new Status(
				IStatus.ERROR,
				UpdateUtils.getPluginId(),
				IStatus.ERROR,
				Policy.bind("InstallLogParser.errors"), //$NON-NLS-1$
				e));
	}
	
	private void parseLog() throws CoreException {
		// 		.install-log template
		//		!CONFIGURATION <configuration-date>
		//		!ACTIVITY <date> <target> <action> <status>

		try {
			String type, status, action;
			StringTokenizer htmlCode;

			while (buffRead.ready()) {

				htmlCode = new StringTokenizer(buffRead.readLine());
				while (!(htmlCode.hasMoreElements())) {
					if (!buffRead.ready())
						return;
					htmlCode = new StringTokenizer(buffRead.readLine());
				}

				type = htmlCode.nextToken().trim();

				if (type.equals(ACTIVITY)) {
					String time = htmlCode.nextToken();
					String date;
					StringBuffer target = new StringBuffer();
					date = htmlCode.nextToken(".");  //$NON-NLS-1$
					htmlCode.nextToken(" ");  //$NON-NLS-1$
					while (htmlCode.countTokens() > 2){
						target.append(" "); //$NON-NLS-1$
						target.append(htmlCode.nextToken());
					}
					
					action = htmlCode.nextToken();
					status = htmlCode.nextToken();
					createActivity(action, time, date, status, target.toString(), currentConfiguration);
				}  else {
					String time = htmlCode.nextToken();
					StringBuffer date;
					date = new StringBuffer();
					while (htmlCode.countTokens() > 0){
						if (date.length() != 0)
							date.append(" "); //$NON-NLS-1$
						date.append(htmlCode.nextToken());
					}
					currentConfiguration = (InstallConfiguration)installConfigMap.get(new Long(time));
				}
			}
		} catch (Exception e) {
			throwCoreException(e);
		}
	}
	
	private void closeLog() {
		try {
			if (buffRead != null)
				buffRead.close();
		} catch (IOException e) {
		} finally {
			buffRead = null;
		}
	}
	private IActivity createActivity(String action, String time, String date, String status, String target, InstallConfiguration config){
		ConfigurationActivity a = new ConfigurationActivity();

		int code = 0;
		if (FEATURE_INSTALL.equals(action))
			code = IActivity.ACTION_FEATURE_INSTALL;
		else if (FEATURE_REMOVE.equals(action))
			code = IActivity.ACTION_FEATURE_REMOVE;
		else if (SITE_INSTALL.equals(action))
			code = IActivity.ACTION_SITE_INSTALL;
		else if (SITE_REMOVE.equals(action))
			code = IActivity.ACTION_SITE_REMOVE;
		else if (UNCONFIGURE.equals(action))
			code = IActivity.ACTION_UNCONFIGURE;
		else if (CONFIGURE.equals(action))
			code = IActivity.ACTION_CONFIGURE;
		else if (REVERT.equals(action))
			code = IActivity.ACTION_REVERT;
		else if (RECONCILIATION.equals(action))
			code = IActivity.ACTION_RECONCILIATION;
		else if (PRESERVED.equals(action))
			code = IActivity.ACTION_ADD_PRESERVED;
		
		a.setAction(code);
		try {
			long activityTime = Long.parseLong(time);
			a.setDate(new Date(activityTime));
		} catch (NumberFormatException e) {
			a.setDate(new Date(date));
		}
		a.setStatus(SUCCESS.equals(status) ? IActivity.STATUS_OK : IActivity.STATUS_NOK);
		a.setLabel(target);
		a.setInstallConfigurationModel(config);
		
		if (config != null && !configContainsActivity(config, a)){
			config.addActivity(a);
		}
		
		return a;
	}
	
	private boolean configContainsActivity(InstallConfiguration c, IActivity a){
		IActivity[] activities = c.getActivities();
		for (int i = 0 ; i<activities.length; i++){
			if (a.equals(activities[i]))
				return true;
		}
		return false;
	}

	public InstallConfiguration[] getConfigurations(){
		Collection configSet = installConfigMap.values();
		InstallConfiguration[] configs = (InstallConfiguration[]) configSet.toArray(new InstallConfiguration[configSet.size()]);
		Arrays.sort(configs, comparator);
		return configs;
	}
}
