//------------------------------------------------------------------------------
// 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.Map;

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;

/**
 * @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;

	// static {
	// Bundle bundle =
	// Platform.getBundle("org.eclipse.epf.library.persistence"); //$NON-NLS-1$
	// //IPath file = new Path("$nl$/migration/migrators.properties");
	// //$NON-NLS-1$
	// IPath file = new Path("/migration/migrators.properties"); //$NON-NLS-1$
	// InputStream is = null;
	// try {
	// is = FileLocator.openStream(bundle, file, false);
	// migrators.load(is);
	// }
	// catch(Exception e) {
	// CommonPlugin.INSTANCE.log(e);
	// }
	// finally {
	// if(is != null) {
	// try {
	// is.close();
	// } catch (IOException e) {
	// CommonPlugin.INSTANCE.log(e);
	// }
	// }
	// }
	// }

	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 static final boolean conversionRequired(String libPath) {
		String currentNsURI = PersistenceUtil.getUMANsURI();
		String libNsURI = PersistenceUtil.getUMANsURI(libPath);
		if (currentNsURI.equals(libNsURI)) {
			return false;
		}
		return getMigrator(libNsURI) != null;
	}

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

	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);
			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$
		}
	}

}
