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

import java.io.File;
import java.util.Collections;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
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.LibraryAlreadyExistsException;
import org.eclipse.epf.library.LibraryNotFoundException;
import org.eclipse.epf.library.LibraryServiceException;
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.services.Services;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.osgi.util.NLS;

/**
 * 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 = "xmi";

	/**
	 * The library XMI file name.
	 */
	public static final String LIBRARY_XMI = "library.xmi";

	/**
	 * The plugin and config spec export file name.
	 */
	public static final String exportFile = "export.xmi"; //$NON-NLS-1$
		
	/**
	 * The library path.
	 */
	public static final String ARG_LIBRARY_PATH = "library.path";

	// The name of the lock file for a library.
	protected static final String LIBRARY_LOCK_FILENAME = ".lock"; //$NON-NLS-1$

	// The absolute path to the managed library.
	protected String path;

	// The file lock for the managed library.
//	private FileLock lock;

	/**
	 * Checks whether the managed method library is locked.
	 * 
	 * @deprecated disable this code for now - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=147106
	 * @return <code>true</code> if the method library is locked
	 */
	public boolean isMethodLibraryLocked() {
		return false;
/*		if (debug) { 
			DebugTrace.print(this, "isMethodLibraryLocked"); //$NON-NLS-1$
		}

		return XMILibraryUtil.isMethodLibraryLocked(getMethodLibraryPath());
*/	}


	/**
	 * 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(String name, Map 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;

			// Lock the method library to prevent access by another EPF composer
			// instance.
			lockMethodLibrary(libraryPath);

			// Open the method library project file.
			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();

			// // this is already moved to LibraryService
			// notifyListeners(ILibraryChangeListener.OPTION_LOADED, null);

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

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

		try {
			File file = new File(uri);
			library = openMethodLibrary(file);
		} 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();
		}

		//An old version library should always be openned from OpenLibraryWizard. Don't want to handle it here.
		VersionUtil.VersionCheckInfo info = VersionUtil.checkLibraryVersion(libraryXMIFile);
		if (info != null && info.result > 0) {
			throw new LibraryServiceException();
		} else if (XMILibraryUtil.isMethodLibraryUpgradeRequired(path.getAbsolutePath(), LIBRARY_XMI)) {
			throw new LibraryServiceException();
		}
				
		try {
			skipEventProcessing = true;

			// Lock the method library to prevent access by another EPF composer
			// instance.
			lockMethodLibrary(path);

			// Open the method library project file.
			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();

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

	/**
	 * Unlocks the managed method library.
	 * @deprecated disable this code for now - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=147106
	 */
	protected void unlockMethodLibrary() {
/*		try {
			if (lock != null) {
				lock.release();
				lock.channel().close();
			}
		} catch (Exception e) {
			LibraryPlugin.getDefault().getLogger().logError(e);
			if (debug) {
				DebugTrace.print(this, "unlockMethodLibrary", e); //$NON-NLS-1$
			}
		}
*/	}

	/**
	 * 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");
		}

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

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

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

		return library;
	}

	/**
	 * Locks the managed method library to prevent access by another EPF
	 * Composer instance.
	 * <p>
	 * The .lock file in the method library folder will be locked. If it does
	 * not exists, a new .lock file will be created.
	 * 
	 * @deprecated disable this code for now - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=147106
	 * @param path
	 *            a <code>File</code> object that contains the path to the
	 *            method library.
	 */
	protected void lockMethodLibrary(File path) {
/*		File lockFile = new File(path, ResourceUtil.LOCK_FILENAME);
		lock = FileUtil.lockFile(lockFile);
*/	}

	/*
	 * (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.
	 * 
	 * @return an absolute path to the method library
	 */
	public String getMethodLibraryPath() {
		if (debug) {
			DebugTrace.print(this, "getMethodLibraryPath"); //$NON-NLS-1$
		}

		java.net.URI libraryURI = getMethodLibraryURI();
		if (libraryURI != null) {
			// File libraryXMIFile = new File(libraryURI.toFileString());
			File libraryXMIFile = new File(libraryURI);
			if (libraryXMIFile.getName().equalsIgnoreCase(LIBRARY_XMI)) {
				libraryXMIFile = libraryXMIFile.getParentFile();
			}
			return libraryXMIFile.getAbsolutePath();
		}
		return null;
	}
}