/*******************************************************************************
 * Copyright (c) 2000, 2015 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.help.internal.search;

import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.*;
import org.eclipse.help.internal.base.util.*;
import org.osgi.framework.*;

/**
 * Table of plugins. Records all plugins, their version, corresponding fragments
 * versions The values are String in format:
 * pluginID\npluginVersion\nfragment1ID\nfragment1Version\nfragment2ID\nfragment2Version
 */
public class PluginVersionInfo extends HelpProperties {
	private static final long serialVersionUID = 1L;

	// Separates plugins and versions in value strings
	protected static final String SEPARATOR = "\n"; //$NON-NLS-1$

	File dir;

	boolean doComparison = true;

	boolean hasChanged = false;

	boolean ignoreSavedVersions;

	Collection<String> added = new ArrayList<String>();

	Collection<String> removed = new ArrayList<String>();

	/**
	 * Creates table of current contributing plugins and their fragments with
	 * versions.
	 *
	 * @param name
	 *            the name of the file to serialize the data to
	 * @param docBundleIds
	 *            Collection of String
	 * @param dir
	 *            location to store the data
	 * @param ignoreSavedVersions
	 *            if true, will cause detect change to ignore saved plugin
	 *            version and behave like there was nothing saved
	 */
	public PluginVersionInfo(String name, Collection<String> docBundleIds, File dir,
			boolean ignoreSavedVersions) {
		super(name, dir);
		this.dir = dir;
		this.ignoreSavedVersions = ignoreSavedVersions;
		createTable(docBundleIds);
	}

	protected void createTable(Collection<String> docBundleIds) {
		// create table of current contributions
		for (Iterator<String> it = docBundleIds.iterator(); it.hasNext();) {
			String bundleId = it.next();
			Bundle pluginBundle = Platform.getBundle(bundleId);
			if (pluginBundle == null) {
				continue;
			}
			StringBuffer pluginVersionAndFragments = new StringBuffer();
			appendBundleInformation(pluginVersionAndFragments, bundleId,
					pluginBundle.getHeaders().get(
							Constants.BUNDLE_VERSION));
			Bundle[] fragmentBundles = Platform.getFragments(pluginBundle);
			if (fragmentBundles != null) {
				for (int f = 0; f < fragmentBundles.length; f++) {
					if (fragmentBundles[f].getState() == Bundle.INSTALLED
							|| fragmentBundles[f].getState() == Bundle.UNINSTALLED)
						continue;
					appendBundleInformation(pluginVersionAndFragments,
							fragmentBundles[f].getSymbolicName(),
							fragmentBundles[f].getHeaders().get(
									Constants.BUNDLE_VERSION));
				}
			}
			this.put(bundleId, pluginVersionAndFragments.toString());
		}
	}

	protected void appendBundleInformation(StringBuffer buffer, String id,
			String version) {
		if (buffer.length()>0)
			buffer.append(SEPARATOR);
		buffer.append(id);
		buffer.append(SEPARATOR);
		buffer.append(version);
	}

	/**
	 * Detects changes in contributions or their version since last time the
	 * contribution table was saved.
	 *
	 * @return true if contributions have changed
	 */
	public boolean detectChange() {
		if (!doComparison)
			return hasChanged;
		// Create table of contributions present before last save()
		HelpProperties oldContrs = new HelpProperties(this.name, dir);
		if (!ignoreSavedVersions) {
			oldContrs.restore();
		}
		// check if contributions changed
		hasChanged = false;
		for (Enumeration<Object> keysEnum = this.keys(); keysEnum.hasMoreElements();) {
			String oneContr = (String) keysEnum.nextElement();
			if (!oldContrs.containsKey(oneContr)) {
				// plugin has been added
				added.add(oneContr);
			} else {
				String versions = (String) this.get(oneContr);
				String oldVersions = (String) oldContrs.get(oneContr);
				if (!compare(versions, oldVersions)) {
					// plugin version changed or fragments changed
					added.add(oneContr);
					removed.add(oneContr);
				}
			}
		}
		for (Enumeration<?> keysEnum = oldContrs.keys(); keysEnum
				.hasMoreElements();) {
			String oneContr = (String) keysEnum.nextElement();
			if (!this.containsKey(oneContr)) {
				// plugin has been removed
				removed.add(oneContr);
			}
		}
		hasChanged = added.size() > 0 || removed.size() > 0;
		doComparison = false;
		return hasChanged;
	}

	/**
	 * @return String - Collection of IDs of contributions that were added or
	 *         upgraded
	 */
	public Collection<String> getAdded() {
		if (doComparison)
			detectChange();
		return added;
	}

	/**
	 * @return String - Collection of IDs of contributions that were removed or
	 *         upgraded
	 */
	public Collection<String> getRemoved() {
		if (doComparison)
			detectChange();
		return removed;
	}

	/**
	 * Saves contributions to a file. After this method is called, calls to
	 * detectChange() will return false.
	 *
	 * @return true if operation was successful
	 */
	@Override
	public boolean save() {
		if (super.save()) {
			doComparison = false;
			hasChanged = false;
			ignoreSavedVersions = false;
			added = new ArrayList<String>();
			removed = new ArrayList<String>();
			return true;
		}
		return false;
	}

	/**
	 * Compares plugins and versions represented as a string for equality String
	 * have form id1\nverison1\nid2\nversion2 String are equal of they contain
	 * the same set of IDs and their corresponding version equal
	 *
	 * @return true if plugins and versions match
	 */
	private boolean compare(String versions, String oldVersions) {
		Map<String, String> versionMap = new HashMap<String, String>();
		for (StringTokenizer t = new StringTokenizer(versions, SEPARATOR, false); t
				.hasMoreTokens();) {
			String pluginOrFragment = t.nextToken();
			if (t.hasMoreTokens()) {
				versionMap.put(pluginOrFragment, t.nextToken());
			}
		}
		Map<String, String> oldVersionMap = new HashMap<String, String>();
		for (StringTokenizer t = new StringTokenizer(oldVersions, SEPARATOR,
				false); t.hasMoreTokens();) {
			String pluginOrFragment = t.nextToken();
			if (t.hasMoreTokens()) {
				oldVersionMap.put(pluginOrFragment, t.nextToken());
			}
		}
		return versionMap.equals(oldVersionMap);
	}
}
