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

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.common.service.versioning.VersionUtil;
import org.eclipse.epf.common.serviceability.DebugTrace;
import org.eclipse.epf.library.AbstractLibraryManager;
import org.eclipse.epf.library.ILibraryResourceManager;
import org.eclipse.epf.library.LibraryAlreadyExistsException;
import org.eclipse.epf.library.LibraryNotFoundException;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryServiceException;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.layout.LayoutResources;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.persistence.PersistenceService;
import org.eclipse.epf.library.project.MethodLibraryProject;
import org.eclipse.epf.library.util.ModelStorage;
import org.eclipse.epf.persistence.MultiFileResourceSetImpl;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.persistence.migration.MappingUtil;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.util.ModifiedTypeMeta;
import org.eclipse.epf.uma.util.UserDefinedTypeMeta;
import org.eclipse.osgi.util.NLS;

import com.ibm.icu.util.Calendar;

/**
 * The default XMI Library Manager implementation.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @author Phong Nguyen Le
 * 
 * @since 1.0
 */
public class XMILibraryManager extends AbstractLibraryManager {
	/**
	 * The supported library type.
	 */
	public static final String LIBRARY_TYPE = Services.XMI_PERSISTENCE_TYPE;

	/**
	 * The library XMI file name.
	 */
	public static final String LIBRARY_XMI = MultiFileSaveUtil.DEFAULT_LIBRARY_MODEL_FILENAME;

	/**
	 * The plugin and config spec export file name.
	 */
	public static final String exportFile = MultiFileSaveUtil.DEFAULT_PLUGIN_EXPORT_FILENAME;

	/**
	 * The library path.
	 */
	public static final String ARG_LIBRARY_PATH = "library.path"; //$NON-NLS-1$
	
	// The absolute path to the managed library.
	protected String path;
	
	private ILibraryResourceManager resourceMgr;

	private IProject project;
	
	private String registerType = "Default";		//$NON-NLS-1$ 
	
	public XMILibraryManager() {
		super();
		resourceMgr = new XMILibraryResourceManager();
	}
	
	protected boolean isReopeningLib = false;
	protected boolean isReopeningSynLib = false;

	/**
	 * Creates a new method library.
	 * 
	 * @param name
	 *            a name for the new method library
	 * @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(final String name, final Map<String, Object> args)
			throws LibraryServiceException {
		final MethodLibrary[] resultHolder = new MethodLibrary[1];
		final LibraryServiceException[] exceptionHolder = new LibraryServiceException[1];
		IWorkspaceRunnable action = new IWorkspaceRunnable() {

			public void run(IProgressMonitor monitor) throws CoreException {
				try {
					resultHolder[0] = doCreateMethodLibrary(name, args);
				}
				catch(LibraryServiceException e) {
					exceptionHolder[0] = e;
				}
			}
			
		};
		try {
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			workspace.run(action, workspace.getRuleFactory().createRule(workspace.getRoot()), IWorkspace.AVOID_UPDATE, null);
		} catch (CoreException e) {
			XMILibraryPlugin.getDefault().getLogger().logError(e);
			throw new LibraryServiceException(e);
		}
		
		if(exceptionHolder[0] != null) {
			throw exceptionHolder[0];
		}
		return resultHolder[0];
	}
		
	private MethodLibrary doCreateMethodLibrary(String name, Map<String, Object> args)
	throws LibraryServiceException {
		if (debug) {
			DebugTrace.print(this, "createMethodLibrary", "name=" + name); //$NON-NLS-1$ //$NON-NLS-2$
		}

		if (name == null || name.length() == 0 || args == null) {
			throw new IllegalArgumentException();
		}

		String path = (String) args.get(ARG_LIBRARY_PATH);
		if (path == null || path.length() == 0) {
			throw new IllegalArgumentException();
		}

		File libraryPath = new File(path);
		File libraryXMIFile = new File(libraryPath, LIBRARY_XMI);
		if (libraryXMIFile.exists()) {
			String msg = NLS.bind(
					XMILibraryResources.libraryAlreadyExistsError_msg,
					libraryPath.getAbsolutePath());
			throw new LibraryAlreadyExistsException(msg);
		}

		if (!libraryPath.exists()) {
			libraryPath.mkdirs();
		}

		try {
			skipEventProcessing = true;
			String regType = (String) args.get(ARG_LIBRARY_REGISTER_TYPE);
			if (regType != null && regType.equals("ConfigExport")) { //$NON-NLS-1$
				String time = Long.toHexString(Calendar.getInstance().getTimeInMillis());
				MethodLibraryProject.openProject(libraryPath.getAbsolutePath(), "ExportLib" + time, //$NON-NLS-1$
						null);		
			} else { 				
				// Open the method library project file.
				project = MethodLibraryProject.openProject(libraryPath.getAbsolutePath(),
						null);
			}
			// Create the resource set.
			ILibraryResourceSet resourceSet = (ILibraryResourceSet) editingDomain
					.getResourceSet();

			// Create a new method library.
			ModelStorage.newLibrary(resourceSet, name, libraryPath
					.getAbsolutePath(), true);
			library = resourceSet.getFirstMethodLibrary();

			// Add a listener to monitor library resource changes.
			addResourceChangedListeners();

			if (debug) {
				DebugTrace.print(this,
						"createMethodLibrary", "library=" + library); //$NON-NLS-1$ //$NON-NLS-2$
			}

			return library;
		} catch (Exception e) {
			XMILibraryPlugin.getDefault().getLogger().logError(e);
			throw new LibraryServiceException(e);
		} finally {
			skipEventProcessing = false;

			// // event processed in LibraryService
			// notifyListeners(ILibraryChangeListener.OPTION_CREATED, null);
		}
	}

	/**
	 * Opens a method library.
	 * 
	 * @param uri
	 *            a method library URI
	 * @return a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodLibrary openMethodLibrary(java.net.URI uri)
			throws LibraryServiceException {
		if (debug) {
			DebugTrace.print(this, "openMethodLibrary"); //$NON-NLS-1$
		}

		if (uri == null) {
			throw new IllegalArgumentException();
		}

		try {
			File file = new File(uri);
			library = openMethodLibrary(file);
		} 
		catch(LibraryServiceException e) {
			throw e;
		}
		catch (Exception e) {
			library = null;
		}

		if (debug) {
			DebugTrace.print(this, "openMethodLibrary", "library=" + library); //$NON-NLS-1$ //$NON-NLS-2$
		}

		return library;
	}

	/**
	 * Opens a method library.
	 * 
	 * @param path
	 *            a <code>File</code> object that contains the path to the
	 *            method library.
	 * @return a <code>MethodLibrary</code>.
	 * @throw <code>LibraryServiceException</code> if an error occurred while
	 *        performing the operation.
	 */
	protected MethodLibrary openMethodLibrary(final File path)
			throws LibraryServiceException {
		final MethodLibrary[] libHolder = new MethodLibrary[1];
		final LibraryServiceException[] exceptionHolder = new LibraryServiceException[1];
		if (ResourcesPlugin.getWorkspace().isTreeLocked()) {
			// if user opens a project from Navigator view, the
			// workspace-runable cannot be run successfully because the
			// workspace is locked at that time and an exception will be
			// thrown.
			// TODO: this work-around however will not defer the notification
			// of resource change events until after the library is opened.
			// This might cause concurrent modification exception.
			//
			try {
				libHolder[0] = doOpenMethodLibrary(path);
			} catch (LibraryServiceException e) {
				exceptionHolder[0] = e;
			}
		} else {
			IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {

				public void run(IProgressMonitor monitor) throws CoreException {
					try {
						libHolder[0] = doOpenMethodLibrary(path);
					} catch (LibraryServiceException e) {
						exceptionHolder[0] = e;
					}
				}
				
			};
			try {
				ResourcesPlugin.getWorkspace().run(workspaceRunnable,
						ResourcesPlugin.getWorkspace().getRoot(),
						IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
			} catch (CoreException e) {
				throw new LibraryServiceException(e);
			}
		}
		if(exceptionHolder[0] != null) {
			throw exceptionHolder[0];
		}
		return libHolder[0];
	}
	
	protected MethodLibrary doOpenMethodLibrary(File path) throws LibraryServiceException {
		File libraryXMIFile = new File(path, LIBRARY_XMI);
		if (!libraryXMIFile.exists()) {
			throw new LibraryNotFoundException();
		}

		VersionUtil.VersionCheckInfo info = VersionUtil.checkLibraryVersion(libraryXMIFile);
		IStatus status = XMILibraryUtil.checkVersion(libraryXMIFile, info);
		if(!status.isOK()) {
			throw new LibraryServiceException(status.getMessage());
		}
		else if(MappingUtil.conversionRequired(libraryXMIFile.getAbsolutePath(), info)) {
			throw new LibraryServiceException(LibraryResources.libUpgradeRequired_err_msg);
		}
		
		try {
			skipEventProcessing = true;

			// Open the method library project file.
			project = MethodLibraryProject.openProject(path.getAbsolutePath(), null);

			// Create the resource set.
			ILibraryResourceSet resourceSet = ((ILibraryResourceSet) editingDomain
					.getResourceSet());

			// Load the method library.
			resourceSet.loadMethodLibraries(URI.createFileURI(libraryXMIFile
					.getAbsolutePath()), Collections.EMPTY_MAP);
			library = resourceSet.getFirstMethodLibrary();

			// Add a listener to monitor library resource changes.
			addResourceChangedListeners();

			System.gc();
			
			return library;
		} catch (Exception e) {
			if (debug) {
				DebugTrace.print(e);
			}
			throw new LibraryServiceException(e);
		} finally {
			firePropertyChange(library, PROP_DIRTY);
			skipEventProcessing = false;
		}
	}

	/**
	 * Opens a method library.
	 * 
	 * @param args
	 *            method library specific arguments
	 * @return a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodLibrary openMethodLibrary(Map args)
			throws LibraryServiceException {
		if (debug) {
			DebugTrace.print(this, "openMethodLibrary"); //$NON-NLS-1$
		}

		if (args == null) {
			throw new IllegalArgumentException();
		}

		String path = (String) args.get(ARG_LIBRARY_PATH);
		if (path == null || path.length() == 0) {
			throw new IllegalArgumentException();
		}

		library = openMethodLibrary(new File(path));

		if (debug) {
			DebugTrace.print(this, "openMethodLibrary", "library=" + library); //$NON-NLS-1$ //$NON-NLS-2$
		}

		return library;
	}

	/**
	 * Reopens the managed method library.
	 * 
	 * @return a method library
	 * @throw <code>LibraryServiceException</code> if an error occurs while
	 *        performing the operation
	 */
	public MethodLibrary reopenMethodLibrary() throws LibraryServiceException {
		if (debug) {
			DebugTrace.print(this, "reopenMethodLibrary"); //$NON-NLS-1$
		}

		try {
			isReopeningLib = true;
			if (library != null && ProcessUtil.isSynFree()) {
				isReopeningSynLib = true;
			}
			library = openMethodLibrary(new File(getMethodLibraryLocation()));
		} finally {
			isReopeningLib = false;
			isReopeningSynLib = false;
		}

		if (debug) {
			DebugTrace.print(this, "reopenMethodLibrary", "library=" + library); //$NON-NLS-1$ //$NON-NLS-2$
		}

		return library;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.library.AbstractLibraryManager#getLibraryPersisterType()
	 */
	protected String getLibraryPersisterType() {
		return Services.XMI_PERSISTENCE_TYPE;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.library.AbstractLibraryManager#createResourceSet()
	 */
	protected ILibraryResourceSet createResourceSet() {
		return PersistenceService.INSTANCE
				.createResourceSet(Services.XMI_PERSISTENCE_TYPE);
	}

	/**
	 * Gets the absolute path to the managed method library.
	 * For distributed library, this is the library's workspace path.
	 * 
	 * @return an absolute path to the method library
	 */
	public String getMethodLibraryLocation() {
		if (debug) {
			DebugTrace.print(this, "getMethodLibraryPath"); //$NON-NLS-1$
		}

		java.net.URI libraryURI = getMethodLibraryURI();
		if (libraryURI != null) {
			File libraryXMIFile = new File(libraryURI);
			if (libraryXMIFile.getName().equalsIgnoreCase(LIBRARY_XMI)) {
				libraryXMIFile = libraryXMIFile.getParentFile();
			}
			return libraryXMIFile.getAbsolutePath();
		}
		return null;
	}
	
	/**
	 * Gets the project of the method library managed by this manager.
	 * 
	 * @return the method library project
	 */
	public IProject getMethodLibraryProject() {
		return project;
	}
	
	public void handleLibraryMoved() {
		if(library == null) {
			return;
		}
		String location = getMethodLibraryLocation();
		if(!project.isOpen() || project.getLocation().equals(new Path(location))) {
			// not moved
			//
			return;
		}
		
		// update URI of all library resources
		//
		Resource libResource = library.eResource();
		if(libResource == null || libResource.getResourceSet() == null) {
			return;
		}
		String newLocation = project.getLocation().toOSString();
		if(libResource.getResourceSet() instanceof MultiFileResourceSetImpl) {
			((MultiFileResourceSetImpl)libResource.getResourceSet()).handleLibraryMoved(newLocation);
		}
		else {
			PersistenceUtil.replaceURIPrefix(new ArrayList<Resource>(libResource.getResourceSet().getResources()), 
					location, newLocation);
		}
	}
	

	/**
	 * get the resource manager for the library
	 * @return ILibraryResourceManager
	 */
	public ILibraryResourceManager getResourceManager() {
		return resourceMgr;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.ILibraryManager#backupMethodLibrary(java.lang.String)
	 */
	public void backupMethodLibrary(String path) {
		String libPathStr = getMethodLibraryLocation();
		File libPath = new File(libPathStr);
		// excude the non-library files that might be locked by rmc.
		// these files may cause backup to fail due to file lock.
		String excludes = ".lock"; //$NON-NLS-1$
		LayoutResources.copyDir(libPath, new File(path), "**", excludes); //$NON-NLS-1$
	}

	private String getRegisterType() {
		return registerType;
	}

	private void setRegisterType(String registerType) {
		this.registerType = registerType;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.ILibraryManager#registerMethodLibrary(org.eclipse.epf.uma.MethodLibrary, java.util.Map)
	 */
	public void registerMethodLibrary(MethodLibrary lib, 
			Map<String, Object> params) throws LibraryServiceException {
		String regType = (String) params.get(ARG_LIBRARY_REGISTER_TYPE);
		if (regType != null) {
			setRegisterType(regType);
		}
		regType = getRegisterType();
		if (regType.equals("ConfigExport")) {//$NON-NLS-1$ 
			//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		
			String name = "library.xmi";	//$NON-NLS-1$;	
			createMethodLibrary(name, params);
			setMethodLibrary(lib);
			return;
		}
		
		//Minimum implementation for defaul register type, to minimize caller code change
		this.library = lib;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.ILibraryManager#unRegisterMethodLibrary()
	 */
	public void unRegisterMethodLibrary() throws LibraryServiceException {
		if (getRegisterType().equals("ConfigExport")) {//$NON-NLS-1$ 
			closeMethodLibrary();
			return;
		}
		//Minimum implementation for defaul register type, to minimize caller code change
		this.library = null;
	}
	
	private Map<String, UserDefinedTypeMeta> userDefinedTypeMap;
	public Collection<UserDefinedTypeMeta> getUserDefinedTypes() {
		return userDefinedTypeMap == null ? null : userDefinedTypeMap.values();
	}
	
	public void addUserDefineType(UserDefinedTypeMeta meta) {
		if (userDefinedTypeMap == null) {
			userDefinedTypeMap = new HashMap<String, UserDefinedTypeMeta>();
		}
		userDefinedTypeMap.put(meta.getId(), meta);
	}
		
	public UserDefinedTypeMeta getUserDefineType(String id) {
		return userDefinedTypeMap == null ? null : userDefinedTypeMap.get(id);
	}
	
	private boolean userDefinedTypeLoaded = false;
	public boolean isUserDefinedTypeLoaded() {
		return userDefinedTypeLoaded;
	}
	
	public void setUserDefinedTypeLoaded(boolean b) {
		userDefinedTypeLoaded = b;
	}
	
	public void prepareToLoadUserDefinedTypes() {
		userDefinedTypeMap = null;
		modifiedTypeMap = null;
	}
	
	private Map<String, ModifiedTypeMeta> modifiedTypeMap;
	public Collection<ModifiedTypeMeta> getModifiedTypes() {
		return modifiedTypeMap == null ? null : modifiedTypeMap.values();		
	}
	
	public void addModifiedType(ModifiedTypeMeta meta) {
		if (modifiedTypeMap == null) {
			modifiedTypeMap = new HashMap<String, ModifiedTypeMeta>();
		}
		modifiedTypeMap.put(meta.getId(), meta);
	}
		
	public ModifiedTypeMeta getModifiedType(String id) {
		return modifiedTypeMap == null ? null : modifiedTypeMap.get(id);
	}
	
}