//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.persistence.migration;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.osgi.framework.Bundle;

/**
 * Utility class with static convenience methods to perform library upgrade from
 * older version.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public final class MappingUtil {

	private static class Migrator {
		Bundle bundle;

		String className;

		String libNsURI;

		IMigrator instance;

		/**
		 * @param bundle
		 * @param className
		 * @param libNsURI
		 */
		public Migrator(Bundle bundle, String className, String libNsURI) {
			super();
			this.bundle = bundle;
			this.className = className;
			this.libNsURI = libNsURI;
		}
	}

	private static Map migrators;
	private static Set oldNsUris = new HashSet();

	public static final IMigrator getMigrator(String libNsURI) {
		if (migrators == null) {
			migrators = new HashMap();
			// Process the "org.eclipse.epf.library.persistence.migrators"
			// extension point
			// contributors.
			IExtensionRegistry extensionRegistry = Platform
					.getExtensionRegistry();
			IExtensionPoint extensionPoint = extensionRegistry
					.getExtensionPoint(
							"org.eclipse.epf.library.persistence", "migrators"); //$NON-NLS-1$ //$NON-NLS-2$
			if (extensionPoint != null) {
				IExtension[] extensions = extensionPoint.getExtensions();
				for (int i = 0; i < extensions.length; i++) {
					IExtension extension = extensions[i];
					String pluginId = extension.getNamespaceIdentifier();
					Bundle bundle = Platform.getBundle(pluginId);
					IConfigurationElement[] configElements = extension
							.getConfigurationElements();
					for (int j = 0; j < configElements.length; j++) {
						IConfigurationElement configElement = configElements[j];
						try {
							String className = configElement
									.getAttribute("class"); //$NON-NLS-1$
							String nsURI = configElement
									.getAttribute("libNsURI"); //$NON-NLS-1$
							if (className != null
									&& className.trim().length() > 0
									&& nsURI != null
									&& nsURI.trim().length() > 0) {
								migrators.put(nsURI, new Migrator(bundle,
										className, nsURI));
							}
						} catch (Exception e) {
							CommonPlugin.INSTANCE.log(e);
						}
					}
				}
			}
		}
		Migrator migrator = (Migrator) migrators.get(libNsURI);
		if (migrator != null) {
			if (migrator.instance == null) {
				try {
					migrator.instance = (IMigrator) migrator.bundle.loadClass(
							migrator.className).newInstance();
				} catch (Exception e) {
					CommonPlugin.INSTANCE.log(e);
				}
			}
			return migrator.instance;
		}
		return null;
	}

	public synchronized static final boolean conversionRequired(String libPath) {
		String currentNsURI = PersistenceUtil.getUMANsURI();
		String libNsURI = PersistenceUtil.getUMANsURI(libPath);

		if (oldNsUris.contains(libNsURI)) {
			return true;
		}
		if (currentNsURI.equals(libNsURI)) {
			return false;
		}
		boolean ret = getMigrator(libNsURI) != null;
		if (ret) {
			oldNsUris.add(libNsURI);
		}
		return ret;
	}

	public static void migrate(String libPath, IProgressMonitor monitor, UpgradeCallerInfo info)
			throws Exception {
		String nsURI = PersistenceUtil.getUMANsURI(libPath);
		IMigrator migrator = getMigrator(nsURI);
		if (migrator != null) {
			migrator.migrate(libPath, monitor, info);
		}
	}

	public static void main(String[] args) {
		String libPath = args[0];
		System.out
				.println("Start migrating method library at '" + libPath + "'..."); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			migrate(libPath, null, null);
			System.out.println();
			System.out.println("Migration successfull."); //$NON-NLS-1$
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println();
			System.err.println("Migration failed."); //$NON-NLS-1$
		}
	}

}
