//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.library;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.epf.common.service.utils.CommandLineRunUtil;
import org.eclipse.epf.library.preferences.LibraryPreferences;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.util.LibraryProblemMonitor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.util.Scope;

/**
 * The default Library Service implementation.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @since 1.0
 */
public class LibraryService implements ILibraryService {

	protected static final int EVENT_CREATE_LIBRARY = 1;

	protected static final int EVENT_OPEN_LIBRARY = 2;

	protected static final int EVENT_REOPEN_LIBRARY = 3;

	protected static final int EVENT_CLOSE_LIBRARY = 4;

	protected static final int EVENT_SET_CURRENT_LIBRARY = 5;

	protected static final int EVENT_SET_CURRENT_CONFIGURATION = 6;

	// The shared instance.
	protected static ILibraryService instance;

	// A map of method libraries to library managers.
	protected Map<MethodLibrary, ILibraryManager> libraryManagers = new HashMap<MethodLibrary, ILibraryManager>();

	// A map of method configurations to configuration managers.
	protected Map<MethodConfiguration, IConfigurationManager> configManagers = new HashMap<MethodConfiguration, IConfigurationManager>();

	// The library service listeners.
	protected List<ILibraryServiceListener> listeners = new ArrayList<ILibraryServiceListener>();

	// The current method library.
	protected MethodLibrary currentLibrary;

	// The current method configuration.
	protected MethodConfiguration currentConfig;

	// If true, the current method library is being closed.
	private boolean closingCurrentLibrary;

	private LibraryProblemMonitor libraryProblemMonitor;
	/**
	 * Returns the shared instance.
	 */
	public static ILibraryService getInstance() {
		if (instance == null) {
			synchronized (LibraryService.class) {
				if (instance == null) {
					instance = new LibraryService();
				}
			}
		}
		return instance;
	}

	/**
	 * Creates a new instance.
	 */
	private LibraryService() {
		init();
	}

	/**
	 * Performs the necessary initialization.
	 */
	protected void init() {
		// Initialize the library manager factory to pre-process the
		// "org.eclipse.epf.library.libraryManagers" extension point.
		LibraryManagerFactory.getInstance();

	}

	/**
	 * Creates a new method library.
	 * 
	 * @param name
	 *            a name for the new method library
	 * @param type
	 *            the method library type
	 * @param args
	 *            method library specific arguments
	 * @return a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodLibrary createMethodLibrary(String name, String type,
			Map<String, Object> params) throws LibraryServiceException {
		if (name == null || type == null || params == null) {
			throw new IllegalArgumentException();
		}

		boolean reopenLibrary = LibraryService.getInstance()
				.getCurrentMethodLibrary() != null;

		try {
			LibraryService.getInstance().closeCurrentMethodLibrary();

			ILibraryManager manager = LibraryManagerFactory.getInstance()
					.createLibraryManager(type);
			MethodLibrary library = manager.createMethodLibrary(name, params);
			if (library != null) {
				// open newly created method library without sending out notification
				//
				library = manager.openMethodLibrary(manager.getMethodLibraryURI());

				setLibraryManager(manager);

				// Set the current library, do this before notifying the library
				// listeners.
				setCurrentMethodLibrary(library);

				// Save the library URI and type to preference store.
				saveMethodLibraryPreferences(manager.getMethodLibraryURI(),
						type);

				notifyListeners(library, EVENT_CREATE_LIBRARY);								
			}

			reopenLibrary = false;

			return library;
		} catch (LibraryServiceException e) {
			throw e;
		} catch (Exception e) {
			throw new LibraryServiceException(e);
		} finally {
			if (reopenLibrary) {
				openLastOpenedMethodLibrary();
			}
		}
	}

	/**
	 * Opens an existing method library.
	 * 
	 * @param type
	 *            the method library type
	 * @param uri
	 *            the method library URI
	 * @return a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodLibrary openMethodLibrary(String type, URI uri)
			throws LibraryServiceException {
		if (uri == null) {
			throw new IllegalArgumentException();
		}

		try {
			ILibraryManager manager = LibraryManagerFactory.getInstance()
					.createLibraryManager(type);
			MethodLibrary library = manager.openMethodLibrary(uri);
			if (library != null) {
				setLibraryManager(manager);

				// Set the current library, do this before notifying the library
				// listeners.
				setCurrentMethodLibrary(library);

				// Save the library URI and type to preference store.
				saveMethodLibraryPreferences(manager.getMethodLibraryURI(),
						type);

				notifyListeners(library, EVENT_OPEN_LIBRARY);
			}
			return library;
		} catch (CreateLibraryManagerException e) {
			throw e;
		} catch (Exception e) {
			throw new LibraryServiceException(e);
		}
	}

	/**
	 * Opens an existing method library.
	 * 
	 * @param type
	 *            the method library type
	 * @param params
	 *            method library specific arguments
	 * @return a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodLibrary openMethodLibrary(String type,
			Map<String, Object> params) throws LibraryServiceException {
		if (params == null) {
			throw new IllegalArgumentException();
		}

		try {
			ILibraryManager manager = LibraryManagerFactory.getInstance()
					.createLibraryManager(type);
			MethodLibrary library = manager.openMethodLibrary(params);
			if (library != null) {
				setLibraryManager(manager);

				// Set the current library, do this before notifying the library
				// listeners.
				setCurrentMethodLibrary(library);

				// Save the library URI and type to preference store.
				saveMethodLibraryPreferences(manager.getMethodLibraryURI(),
						type);

				notifyListeners(library, EVENT_OPEN_LIBRARY);
			}
			return library;
		} catch (CreateLibraryManagerException e) {
			throw e;
		} catch (Exception e) {
			throw new LibraryServiceException(e);
		}
	}

	/**
	 * Opens the last opened method library.
	 * 
	 * @return a method library or <code>null</code>
	 */
	public MethodLibrary openLastOpenedMethodLibrary() {
		if (CommandLineRunUtil.getInstance().isNeedToRun()) {
			return null;
		}
		
		String savedMethodLibraryURI = LibraryPreferences
				.getSavedMethodLibraryURI();
		try {
			URI uri = new URI(savedMethodLibraryURI);
			if (uri.getPath().length() == 0) {
				return null;
			}

			String type = LibraryPreferences.getSavedMethodLibraryType();
			if (type == null || type.length() == 0) {
				return null;
			}

			return openMethodLibrary(type, uri);
		} catch (Exception e) {
			LibraryPlugin.getDefault().getLogger().logWarning(
					"Unable to open the last opened method library '" //$NON-NLS-1$
							+ savedMethodLibraryURI + "'."); //$NON-NLS-1$
			LibraryPreferences.setSavedMethodLibraryURI(""); //$NON-NLS-1$
		}
		return null;
	}

	/**
	 * Reopens a method library.
	 * 
	 * @param library
	 *            a method library
	 * @return a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodLibrary reopenMethodLibrary(MethodLibrary library)
			throws LibraryServiceException {
		ILibraryManager manager = getLibraryManager(library);
		if (manager != null) {
			try {
				removeLibraryManager(manager);
				library = manager.reopenMethodLibrary();

				// Re-register the library manager since the library instance
				// will be changed.
				setLibraryManager(manager);

				// Set the current library, do this before notifying the library
				// listeners.
				setCurrentMethodLibrary(library);

				notifyListeners(library, EVENT_REOPEN_LIBRARY);
			} catch (Exception e) {
				throw new LibraryServiceException(e);
			}
		}
		return null;
	}

	/**
	 * Reopens the current method library.
	 * 
	 * @return a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodLibrary reopenCurrentMethodLibrary()
			throws LibraryServiceException {
		return reopenMethodLibrary(currentLibrary);
	}

	/**
	 * Saves a method library.
	 * 
	 * @param library
	 *            a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public void saveMethodLibrary(MethodLibrary library)
			throws LibraryServiceException {
		ILibraryManager manager = getLibraryManager(library);
		if (manager != null) {
			manager.saveMethodLibrary();
		}
	}

	/**
	 * Saves the current method library.
	 * 
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public void saveCurrentMethodLibrary() throws LibraryServiceException {
		saveMethodLibrary(currentLibrary);
	}

	/**
	 * Closes a method library.
	 * <p>
	 * This automatically disposes its library manager and the configuration
	 * managers that manage the method configurations in the method library.
	 * 
	 * @param library
	 *            a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public void closeMethodLibrary(MethodLibrary library)
			throws LibraryServiceException {
		ILibraryManager manager = getLibraryManager(library);
		if (manager != null) {
			notifyListeners(library, EVENT_CLOSE_LIBRARY);
			manager.closeMethodLibrary();
			if (currentLibrary == library) {
				setCurrentMethodLibrary(null);
				setCurrentMethodConfiguration(null);
			}
			removeLibraryManager(manager);
			manager.dispose();
		}
	}

	/**
	 * Closes the current method library.
	 * 
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public synchronized void closeCurrentMethodLibrary()
			throws LibraryServiceException {
		if (closingCurrentLibrary)
			return;
		try {
			closingCurrentLibrary = true;
			if (currentLibrary != null) {
				closeMethodLibrary(currentLibrary);
			}
		} finally {
			closingCurrentLibrary = false;
		}
	}

	/**
	 * Replaces a the method library.
	 * 
	 * @param oldLibrary
	 *            the old method library
	 * @param newLibrary
	 *            the new method library
	 */
	public void replaceMethodLibrary(MethodLibrary oldLibrary,
			MethodLibrary newLibrary) {
		ILibraryManager manager = getLibraryManager(oldLibrary);
		if (manager != null) {
			removeLibraryManager(manager);

			// Set the new library instance to prevent the library manager from
			// referencing the old library instance.
			manager.setMethodLibrary(newLibrary);

			setLibraryManager(manager);
		}
	}

	/**
	 * Adds a listener to monitor Library Service events.
	 * 
	 * @param listener
	 *            a library service listener
	 */
	public void addListener(ILibraryServiceListener listener) {
		listeners.add(listener);
	}

	/**
	 * Removes a listener that was added to monitor Library Service events.
	 * 
	 * @param listener
	 *            a library service listener
	 */
	public void removeListener(ILibraryServiceListener listener) {
		listeners.remove(listener);
	}

	/**
	 * Gets the current method library.
	 * 
	 * @return a method library
	 */
	public MethodLibrary getCurrentMethodLibrary() {
		return currentLibrary;
	}

	/**
	 * Sets the current method library.
	 * 
	 * @param library
	 *            a method library
	 */
	public void setCurrentMethodLibrary(MethodLibrary library) {
		currentLibrary = library;
		notifyListeners(library, EVENT_SET_CURRENT_LIBRARY);
	}

	/**
	 * Gets the current method library location path.
	 * <p>
	 * Note: A file-based method library may return <code>null</code>.
	 * 
	 * @return an absolute path to the current method library
	 */
	public String getCurrentMethodLibraryLocation() {
		ILibraryManager manager = getLibraryManager(currentLibrary);
		if (manager != null) {
			return manager.getMethodLibraryLocation();
		} else {
			return null;
		}
	}

	/**
	 * Gets the library manager for a method library.
	 * 
	 * @param library
	 *            a method library
	 * @return a library manager
	 */
	public ILibraryManager getLibraryManager(MethodLibrary library) {
		return (ILibraryManager) libraryManagers.get(library);
	}

	public void removeLibraryManager(ILibraryManager libMgr) {
		if (libMgr != null) {
			MethodLibrary lib = libMgr.getMethodLibrary();
			if (lib != null) {
				removeConfigurationManagers(lib);
				libraryManagers.remove(lib);
			}
		}
	}

	public void setLibraryManager(ILibraryManager libMgr) {
		MethodLibrary lib = libMgr.getMethodLibrary();
		if (lib != null) {
			libraryManagers.put(lib, libMgr);
		}

	}

	/**
	 * Gets the library manager for the current method library.
	 * 
	 * @return a library manager
	 */
	public ILibraryManager getCurrentLibraryManager() {
		return getLibraryManager(currentLibrary);
	}

	/**
	 * Creates a new method configuration.
	 * 
	 * @param name
	 *            a name for the new method configuration
	 * @param library
	 *            the containing method library
	 * @return a method configuration
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodConfiguration createMethodConfiguration(String name,
			MethodLibrary library) throws LibraryServiceException {
		if (name == null || library == null) {
			throw new IllegalArgumentException();
		}

		MethodConfiguration config;
		List configs = library.getPredefinedConfigurations();
		for (Iterator it = configs.iterator(); it.hasNext();) {
			config = (MethodConfiguration) it.next();
			if (name.equals(config.getName())) {
				throw new ConfigurationAlreadyExistsException();
			}
		}

		config = UmaFactory.eINSTANCE.createMethodConfiguration();
		config.setName(name);
		configs.add(config);
		return config;
	}
	
	
	/**
	 * Gets the current method configuration.
	 * 
	 * @return a method configuration
	 */
	public MethodConfiguration getCurrentMethodConfiguration() {
		return currentConfig;
	}

	/**
	 * Sets the current method configuration.
	 * 
	 * @param config
	 *            a method configuration
	 */
	public void setCurrentMethodConfiguration(MethodConfiguration config) {
		currentConfig = config;
		notifyListeners(config, EVENT_SET_CURRENT_CONFIGURATION);
	}

	/**
	 * Gets the configuration manager for a method configuration.
	 * 
	 * @param config
	 *            a method configuration
	 * @return a configuration manager
	 */
	public synchronized IConfigurationManager getConfigurationManager(
			MethodConfiguration config) {
		if (config == null) {
			throw new IllegalArgumentException();
		}
		if (config instanceof Scope) {	//Don't cache it
			new ConfigurationManager(config);
		}
		
		IConfigurationManager manager = (IConfigurationManager) configManagers
				.get(config);
		if (manager == null) {
			manager = new ConfigurationManager(config);
			configManagers.put(config, manager);
		}
		return manager;
	}

	public void removeConfigurationManager(MethodConfiguration config) {
		if (config == null) {
			throw new IllegalArgumentException();
		}

		IConfigurationManager mgr = (IConfigurationManager) configManagers
				.remove(config);
		if (mgr != null) {
			mgr.dispose();
		}
	}

	public void removeConfigurationManagers(MethodLibrary library) {
		if (library == null) {
			throw new IllegalArgumentException();
		}

		MethodConfiguration[] configs = LibraryServiceUtil
				.getMethodConfigurations(library);
		for (int i = 0; i < configs.length; i++) {
			removeConfigurationManager(configs[i]);
		}
	}

	/**
	 * Gets the configuration manager for the current method configuration.
	 * 
	 * @return a configuration manager
	 */
	public IConfigurationManager getCurrentConfigurationManager() {
		if (currentConfig != null) {
			return getConfigurationManager(currentConfig);
		}
		return null;
	}

	/**
	 * Sends a method library related event to all library service listeners.
	 */
	protected void notifyListeners(final MethodLibrary library, int eventId) {
		for (Iterator<ILibraryServiceListener> it = new ArrayList<ILibraryServiceListener>(
				listeners).iterator(); it.hasNext();) {
			final ILibraryServiceListener listener = it.next();
			switch (eventId) {
			case EVENT_CREATE_LIBRARY:
				SafeUpdateController.asyncExec(new Runnable() {
					public void run() {
						listener.libraryCreated(library);
					}
				});
				break;
			case EVENT_OPEN_LIBRARY:
				SafeUpdateController.asyncExec(new Runnable() {
					public void run() {
						listener.libraryOpened(library);
					}
				});
				break;
			case EVENT_REOPEN_LIBRARY:
				SafeUpdateController.asyncExec(new Runnable() {
					public void run() {
						listener.libraryReopened(library);
					}
				});
				break;
			case EVENT_CLOSE_LIBRARY:
				SafeUpdateController.asyncExec(new Runnable() {
					public void run() {
						listener.libraryClosed(library);
					}
				});
				break;
			case EVENT_SET_CURRENT_LIBRARY:
				SafeUpdateController.asyncExec(new Runnable() {
					public void run() {
						listener.librarySet(library);
					}
				});
				break;
			}
		}
	}

	/**
	 * Sends a method configuration related event to all library service
	 * listeners.
	 */
	protected void notifyListeners(final MethodConfiguration config, int eventId) {
		for (Iterator<ILibraryServiceListener> it = new ArrayList<ILibraryServiceListener>(
				listeners).iterator(); it.hasNext();) {
			final ILibraryServiceListener listener = it.next();
			switch (eventId) {
			case EVENT_SET_CURRENT_CONFIGURATION:
				SafeUpdateController.syncExec(new Runnable() {
					public void run() {
						listener.configurationSet(config);
					}
				});
				break;
			}
		}
	}

	/**
	 * Saves the method library URI and type to preference store.
	 * 
	 * @param uri
	 *            the method library URI
	 * @param type
	 *            the menthod library type
	 */
	protected void saveMethodLibraryPreferences(URI uri, String type) {
		LibraryPreferences.setSavedMethodLibraryURI(uri.toString());
		LibraryPreferences.setSavedMethodLibraryType(type);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.ILibraryService#registerMethodLibrary(org.eclipse.epf.uma.MethodLibrary, java.lang.String, java.util.Map)
	 */
	public void  registerMethodLibrary(MethodLibrary lib, String type,
			Map<String, Object> params) throws LibraryServiceException {
		//For now, still simply wraping up old implementation (copied from ConfigurationExportService) for smoother change; will definetly change later
		//so that creating a new lib would not be needed		
		ILibraryManager libMgr = LibraryManagerFactory.getInstance()
			.createLibraryManager(type);
		libMgr.registerMethodLibrary(lib, params);
		//libMgr.createMethodLibrary(name, params);
		//libMgr.setMethodLibrary(lib);
		LibraryService.getInstance().setLibraryManager(libMgr);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.ILibraryService#unRegisterMethodLibrary(org.eclipse.epf.uma.MethodLibrary)
	 */
	public void unRegisterMethodLibrary(MethodLibrary lib) throws LibraryServiceException {
		//For now, still simply wraping up old implementation (copied from ConfigurationExportService) for smoother change
		ILibraryManager libMgr = getLibraryManager(lib);
		if (libMgr == null) {
			return;
		}
		removeLibraryManager(libMgr);
		//libMgr.closeMethodLibrary();
		libMgr.unRegisterMethodLibrary();
		libMgr.dispose();
	}
	
	public LibraryProblemMonitor getLibraryProblemMonitor() {
		if (libraryProblemMonitor == null) {
			libraryProblemMonitor = new LibraryProblemMonitor();
		}
		return 	libraryProblemMonitor;
	}

}
