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

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.epf.resourcemanager.ResourceDescriptor;
import org.eclipse.epf.resourcemanager.ResourceManager;
import org.eclipse.epf.resourcemanager.ResourcemanagerFactory;
import org.eclipse.epf.resourcemanager.ResourcemanagerPackage;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.UmaPackage;

/**
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class Recoverer {

	private static final FilenameFilter filenameFilter = new FilenameFilter() {

		public boolean accept(File arg0, String arg1) {
			if (new File(arg0, arg1).isDirectory())
				return true;
			return arg1.toLowerCase().endsWith(".xmi"); //$NON-NLS-1$
		}

	};

	private static final Map LOAD_OPTIONS = new HashMap();

	private static final Map SAVE_OPTIONS = new HashMap();

	static {
		LOAD_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
		ExtendedMetaData extMetaData = new BasicExtendedMetaData();
		extMetaData
				.putPackage(
						"http:///com/ibm/uma/resourcemanager.ecore", ResourcemanagerPackage.eINSTANCE); //$NON-NLS-1$
		extMetaData.putPackage(
				"http:///com/ibm/uma.ecore", UmaPackage.eINSTANCE); //$NON-NLS-1$
		LOAD_OPTIONS.put(XMLResource.OPTION_EXTENDED_META_DATA, extMetaData);

		SAVE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
	}

	public static final void recover(String libDirPath) throws IOException {
		File libDir = new File(libDirPath);
		MultiFileXMIResourceImpl resMgrResource = new MultiFileXMIResourceImpl(
				URI.createFileURI(libDirPath + File.separator
						+ MultiFileResourceSetImpl.RESMGR_XMI));
		resMgrResource.load(LOAD_OPTIONS);
		ResourceManager resMgr = (ResourceManager) resMgrResource.getContents()
				.get(0);
		addToResourceManager(resMgr, libDir);
		resMgrResource.save(SAVE_OPTIONS);
	}

	private static void addToResourceManager(ResourceManager resMgr, File file) {
		if (file.isDirectory()) {
			File[] files = file.listFiles(filenameFilter);
			for (int i = 0; i < files.length; i++) {
				addToResourceManager(resMgr, files[i]);
			}
		} else {
			MethodElement e = null;
			try {
				MultiFileXMIResourceImpl resource = new MultiFileXMIResourceImpl(
						URI.createFileURI(file.getAbsolutePath()));
				resource.load(LOAD_OPTIONS);
				if (!resource.getContents().isEmpty()) {
					Object obj = resource.getContents().get(0);
					if (obj instanceof MethodElement) {
						e = (MethodElement) obj;
					}
				}
			} catch (IOException ex) {
			}
			if (e != null) {
				String guid = e.getGuid();
				if (guid != null && guid.trim().length() != 0) {
					// check if a URI map entry already exists for this guid in
					// resource mananger
					//
					for (Iterator iter = resMgr.getResourceDescriptors()
							.iterator(); iter.hasNext();) {
						ResourceDescriptor resDescriptor = (ResourceDescriptor) iter
								.next();
						if (resDescriptor.getId().equals(guid)) {
							return;
						}
					}

					ResourceDescriptor resDescriptor = ResourcemanagerFactory.eINSTANCE
							.createResourceDescriptor();
					resDescriptor.setId(guid);
					resDescriptor.setUri(URI.createFileURI(
							file.getAbsolutePath()).deresolve(
							resMgr.eResource().getURI()).toString());
					resMgr.getResourceDescriptors().add(resDescriptor);
					System.out
							.println("added '" + resDescriptor.getUri() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
		}
	}

	public static void main(String[] args) {
		String libDir = args[0];
		try {
			recover(libDir);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
