//------------------------------------------------------------------------------
// 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.internal.migration;

import java.io.File;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.util.ResourceUtil;
import org.eclipse.epf.library.xmi.IDiagramMigration;
import org.eclipse.epf.persistence.MultiFileResourceSetImpl;
import org.eclipse.epf.persistence.migration.MigrationUtil;
import org.eclipse.epf.persistence.migration.UpgradeCallerInfo;
import org.eclipse.epf.persistence.util.PersistenceResources;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.Example;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.GuidanceDescription;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ReusableAsset;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.Whitepaper;

/**
 * @author Weiping Lu - Feb 12, 2007
 * @since 1.2
 */
public class Migrator103 extends MigratorBase {
	
	private Map<String, Process> diagramElemMap; 
	
	public void migrate(String libPath, IProgressMonitor monitor) throws Exception {
		migrate(libPath, monitor, null);
	}
	
	public void migrate(String libPath, IProgressMonitor monitor, UpgradeCallerInfo info) throws Exception {
		File libFile = new File(libPath);

		ResourceUtil.open(libFile.getParent(), monitor);

		MultiFileResourceSetImpl resourceSet = null;
		
		diagramElemMap = new LinkedHashMap<String, Process>();
		try {
			// load the library
			//
			updateStatus(monitor, PersistenceResources.loadLibraryTask_name);

			resourceSet = new MultiFileResourceSetImpl(false);
						
			resourceSet.getLoadOptions().put(
					XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);

			MethodLibrary lib = resourceSet.loadLibrary(libPath);
						
			// load all elements in memory
			//
			updateStatus(monitor, PersistenceResources.loadResourcesTask_name);
			
			updateAllContents(monitor, lib);					
			
			// save all files
			//
			updateStatus(monitor, PersistenceResources.saveLibraryTask_name);
			Map saveOptions = resourceSet.getDefaultSaveOptions();
			resourceSet.save(saveOptions, true);

			updateStatus(monitor,
					PersistenceResources.refreshLibraryFilesTask_name);
			
			
			ResourceUtil.refreshResources(lib, monitor);
			
			diagramMigrate(diagramElemMap, monitor);	

		} finally {
			if (resourceSet != null) {
				resourceSet.reset();
				resourceSet = null;
			}
		}

	}

	protected static void diagramMigrate(Map<String, Process> diagramElemMap, IProgressMonitor monitor) {
		// Convert diagrams 			
		IDiagramMigration idm = (IDiagramMigration) ExtensionManager.getExtension("org.eclipse.epf.library.xmi", "diagramMigration"); 			//$NON-NLS-1$ //$NON-NLS-2$
		if (idm != null && !diagramElemMap.isEmpty()) {
			try {
				idm.migrate(diagramElemMap.values());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	protected void updateElement(MethodElement element, IProgressMonitor monitor) throws Exception {
		updateElement(element, diagramElemMap, monitor);
	}

	protected static void updateElement(MethodElement element, Map<String, Process> diagramElemMap, IProgressMonitor monitor) throws Exception {
		if (element instanceof CapabilityPattern ||
			element instanceof DeliveryProcess) {
			String guid = element.getGuid();
			Process proc = diagramElemMap.get(guid);
			if (proc == null) {
				diagramElemMap.put(element.getGuid(), (Process) element);
			} else {
				assert(proc == element);
			}
		}
		MigrationUtil.formatValue(element);
		handleTypeConvert(element);
	}
	
	private static void handleTypeConvert(MethodElement element) throws Exception {
		if (	element instanceof Example 			||
				element instanceof ReusableAsset 	||
				element instanceof Whitepaper) {			
			Guidance guidance = (Guidance) element;
			ContentDescription pres = convert(guidance.getPresentation());
			if (pres != null) {
				guidance.setPresentation(pres);
			}			
		}
	}
	
	private static GuidanceDescription convert(ContentDescription oldObj) {
		if (oldObj == null) {
			return null;
		}
		GuidanceDescription newObj = UmaFactory.eINSTANCE.createGuidanceDescription();		
		Resource res = oldObj.eResource();
		res.getContents().remove(oldObj);
		res.getContents().add(newObj);
		
		List properties = oldObj.getInstanceProperties();		
		if (properties != null) {
			for (int i = 0; i < properties.size(); i++) {
				EStructuralFeature feature = (EStructuralFeature) properties.get(i);
				Object value = oldObj.eGet(feature);
				newObj.eSet(feature, value);
			}
		}
				
		return newObj;
	}

}
