//------------------------------------------------------------------------------
// 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.Collections;
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.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.common.serviceability.DebugTrace;
import org.eclipse.epf.common.serviceability.VersionUtil;
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.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.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();
	}

	/**
	 * 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) {
			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(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$
		}

		library = openMethodLibrary(new File(getMethodLibraryLocation()));

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