/*******************************************************************************
 * 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.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 {
		    // throws FileNotFoundException, IOException
		    InputStream is = new FileInputStream(logPath.toOSString());
		    // throws UnsupportedEncodingException
		    InputStreamReader isr = new InputStreamReader(is,"UTF-8");
		    buffRead = new BufferedReader(isr);
		} catch (Exception 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;
	}
}
