//------------------------------------------------------------------------------
// 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.importing.services;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.epf.common.serviceability.VersionUtil;
import org.eclipse.epf.common.ui.util.MsgBox;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.export.services.LibraryDocument;
import org.eclipse.epf.export.services.PluginExportService;
import org.eclipse.epf.importing.ImportPlugin;
import org.eclipse.epf.importing.ImportResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.project.MethodLibraryProject;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.ui.util.ConvertGuidanceType;
import org.eclipse.epf.library.ui.util.TypeConverter;
import org.eclipse.epf.library.ui.wizards.OpenLibraryWizard;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.ResourceUtil;
import org.eclipse.epf.persistence.migration.UpgradeCallerInfo;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;

import com.ibm.icu.util.Calendar;


/**
 * Imports a library configuration.
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class ConfigurationImportService {

	private boolean localDebug = false;
	
	private UpgradeCallerInfo upGradeInfo;
	
	private ConfigurationImportData data;

	LibraryDocument importingLibDoc = null;

	LibraryDiffManager diffMgr = null;

	ConfigSpecsImportManager specsMgr = null;
	
	/**
	 * Creates a new instance.
	 */
	public ConfigurationImportService(ConfigurationImportData data) {
		this.data = data;
	}

	/**
	 * Analyzes the imported library with respect to the base library.
	 */
	public void analyze(IProgressMonitor monitor) {
		try {
			if (monitor != null) {
				monitor.setTaskName(ImportResources.ConfigurationImportService_MSG0);
			}

			data.getErrorInfo().clear();

			// Prepare the library files.
			String path = data.llData.getParentFolder();
			if (path.indexOf(File.separator + LibraryDocument.libraryFile) < 0) {
				path += File.separator + LibraryDocument.libraryFile;
			}
			File importingLibPath = new File(path);
			
			boolean isLibraryFile = true;
			if (!importingLibPath.exists()) {
				importingLibPath = new File(importingLibPath.getParentFile(),
						LibraryDocument.exportFile);
				isLibraryFile = false;
			}

			if (!importingLibPath.exists()) {
				data
						.getErrorInfo()
						.addError(
								NLS.bind(ImportResources.ConfigurationImportService_MSG1, importingLibPath.getParent())); 
				return;
			}

			boolean handleVersion = isLibraryFile;
			if (handleVersion) {
				upGradeInfo = new ConfigurationImportService.UpgradeInfo(UpgradeCallerInfo.upgradeImportConfig, importingLibPath);
				if (! handleToolVersion(importingLibPath, upGradeInfo)) {
					data
					.getErrorInfo()
					.addError(
							NLS.bind(ImportResources.ImportConfigurationWizard_ERR_Import_configuration, importingLibPath.getParent())); 

					return;
				}
				if (upGradeInfo.getCopiedLibFile() != null) {
					importingLibPath = upGradeInfo.getCopiedLibFile();
				}
			}
						
			importingLibDoc = new LibraryDocument(importingLibPath);
			
			if (! handleVersion) {
				String versionError = versionCheck(importingLibPath.getAbsolutePath(), 
										ImportResources.importConfigWizard_title);
				if (versionError != null) {
					data.getErrorInfo().addError(versionError);
					return;
				}
			}

			boolean isConfigSpecs = importingLibDoc.isConfigSpecsOnly();

			if (isConfigSpecs) {

				specsMgr = new ConfigSpecsImportManager();

				// Scan the library file for configuration information.
				data.specs = specsMgr.getConfigSpecs(importingLibDoc);

			} else {
				if (!isLibraryFile) {
					data
					.getErrorInfo()
					.addError(
							NLS.bind(ImportResources.ConfigurationImportService_MSG1, importingLibPath.getParent())); 
					return;
				}
				data.specs = null;

				// Open the library and compare the difference.
				
				// need to open and close the library to have the project resources initialized properly
				String libDir = importingLibPath.getParentFile().getAbsolutePath();

				String projectName = "Configuration Import Project (" //$NON-NLS-1$
						+ Integer.toHexString(libDir.hashCode()) + ")"; //$NON-NLS-1$
				
				MethodLibraryProject.openProject(libDir, projectName, monitor);
				try {
					MethodLibrary importLibraty = LibraryUtil
							.loadLibrary(importingLibPath.getAbsolutePath());
					MethodLibrary baseLibrary = LibraryService.getInstance()
							.getCurrentMethodLibrary();
					
					handleTypeChanges(baseLibrary, importLibraty);
					
					String baseLibDir = null;
					try {	//Not neccessary, but prevent introducing any potential regression due to this change
						File bFile = new File(baseLibrary.eResource().getURI().toFileString()).getParentFile();;
						baseLibDir = bFile.getAbsolutePath();
					} catch (Throwable e) {						
					}
					if (libDir.equalsIgnoreCase(baseLibDir)) {
						data
								.getErrorInfo()
								.addError(
										NLS.bind(ImportResources.ConfigurationImportService_MSG2, importingLibPath.getParent())); 
						return;
					}
					
					fixImportLibrarySystemPackageGUIDs(baseLibrary, importLibraty);
					
					diffMgr = new LibraryDiffManager(baseLibrary, importLibraty);
					diffMgr.buildDiffTree();
					
					if (localDebug) {
						diffMgr.rootDiffTree.debugDump();
					}
					
				} catch (RuntimeException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				MethodLibraryProject.closeProject(libDir, monitor);
				MethodLibraryProject.deleteProject(libDir, monitor);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

	/**
	 * Returns the import data.
	 */
	public ConfigurationImportData getImportData() {
		return data;
	}

	/**
	 * Returns spec only attribute.
	 */
	public boolean isSpecsOnly() {
		return (data.specs != null);
	}

	/**
	 * Returns the diff tree.
	 */
	public ElementDiffTree getDiffTree() {
		return diffMgr.getDiffTree();
	}

	/**
	 * Returns the import library.
	 */
	public MethodLibrary getImportingLibrary() {
		return diffMgr.getImportingLibrary();
	}

	/**
	 * Performs the import.
	 */
	public void performImport(final IProgressMonitor monitor) {
		
		// need to disable the workspace refreshing
		boolean refresh = RefreshJob.getInstance().isEnabled();
		if(refresh) {
			// disable resource refreshing during import
			//
			RefreshJob.getInstance().setEnabled(false);
		}
		
		try {
			if (monitor != null) {
				monitor.setTaskName(ImportResources.ConfigurationImportService_MSG3);
			}

			if (isSpecsOnly()) {
				specsMgr.doImport(data.specs);
			} else {
				LibraryImportManager importingMgr = new LibraryImportManager(diffMgr, data.importList);			
				importingMgr.doMerge(data.replaceExisting, monitor);
			}
			
			// refresh library files in workspace
			//
			MethodLibrary lib = LibraryService.getInstance().getCurrentMethodLibrary();
			ResourceUtil.refreshResources(lib, monitor);
			
		} catch (Exception e) {
			ImportPlugin.getDefault().getLogger().logError(e);
		} finally {
			if(refresh) {
				// re-enable resource refreshing 
				//
				RefreshJob.getInstance().setEnabled(true);
			}
			if (upGradeInfo != null) {
				upGradeInfo.removeCopiedLibrary();
				upGradeInfo = null;
			}
		}	
		
		try {
			// Reopen the library.
			LibraryService.getInstance().reopenCurrentMethodLibrary();		

		} catch (Exception e) {
			ImportPlugin.getDefault().getLogger().logError(e);
		}
	}
	
	/**
	 * Checks the tool version.
	 */
	public static String versionCheck(final String xmlPath, final String title) {
		final String[] ret = new String[1];
		ret[0] = null;
		SafeUpdateController.syncExec(new Runnable() {	
			public void run() {				
				VersionUtil.VersionCheckInfo info = VersionUtil.checkLibraryVersion(new File(xmlPath));
				if (info == null) {
					ret[0] = NLS.bind(ImportResources.versionMismatch_oldData_unknown, new Object[] {
							Platform.getProduct().getName()});					
				} else {
					if (info.result < 0) {
						if (info.toolID.equals(VersionUtil.getPrimaryToolID())) {
							ret[0] = NLS.bind(ImportResources.versionMismatch_oldData, new Object[] {
									info.toolVersion, Platform.getProduct().getName()});
						} else {
							ret[0] = NLS.bind(ImportResources.versionMismatch_oldData_unknown, new Object[] {
									Platform.getProduct().getName()});					
						}
					} else if (info.result > 0) {
						if (info.toolID.equals(VersionUtil.getPrimaryToolID())) {
							ret[0] = NLS.bind(ImportResources.versionMismatch_oldTool, new Object[] {
									info.toolVersion, Platform.getProduct().getName()});
						} else {
							ret[0] = NLS.bind(ImportResources.versionMismatch_oldTool_unknown, new Object[] {
									Platform.getProduct().getName()});
						}
					} 
				}
				if (ret[0] != null) {
					ImportPlugin.getDefault().getMsgDialog().displayError(title, ret[0]);					
				}
			}
		});		
		return ret[0];
	}
	
	/**
	 * Fixes the imported library's system package guids with those base's.
	 */
	public static void fixImportLibrarySystemPackageGUIDs(MethodLibrary baseLibrary, MethodLibrary importLibraty) {
		HashMap pluginsMap = new HashMap();
		List plugins = baseLibrary.getMethodPlugins();
		for (int i=0; i < plugins.size(); i++) {
			MethodPlugin plugin = (MethodPlugin) plugins.get(i);
			pluginsMap.put(plugin.getGuid(), plugin);
		}
		if (pluginsMap.isEmpty()) {
			return;
		}
		
		List importPluginsToFix = new ArrayList();
		List importPlugins = importLibraty.getMethodPlugins();
		for (int i=0; i < importPlugins.size(); i++) {
			MethodPlugin plugin = (MethodPlugin) importPlugins.get(i);
			if (pluginsMap.containsKey(plugin.getGuid())) {
				importPluginsToFix.add(plugin);
			}
		}
		
		for (int i=0; i < importPluginsToFix.size(); i++) {
			MethodPlugin importPlugin = (MethodPlugin) importPluginsToFix.get(i);
			MethodPlugin basePlugin = (MethodPlugin) pluginsMap.get(importPlugin.getGuid());
			if (basePlugin == null) {
				continue;
			}
			List importPackages = TngUtil.getAllSystemPackages(importPlugin);
			HashMap importPackageMap = new HashMap();
			for (int j=0; j < importPackages.size(); j++) {
				MethodElement importPackage = (MethodElement) importPackages.get(j);
				importPackageMap.put(importPackage.getName(), importPackage);
			}
			
			List basePackages = TngUtil.getAllSystemPackages(basePlugin);			
			for (int j=0; j < basePackages.size(); j++) {
				MethodElement basePackage = (MethodElement) basePackages.get(j);
				MethodElement importPackage = (MethodElement) importPackageMap.get(basePackage.getName());
				if (importPackage == null) {
					continue;
				}
				String guid = basePackage.getGuid();
				if (! importPackage.getGuid().equals(guid)) {
					importPackage.setGuid(guid);
				}
			}
		}			
	}
	
	private void handleTypeChanges(MethodLibrary baseLib, MethodLibrary importLib) {
		HashMap baseMap = new HashMap();
		collectPotentialTypeChanged(baseLib, baseMap);
		HashMap importMap = new HashMap();
		collectPotentialTypeChanged(importLib, importMap);
		handleTypeChanges(baseMap, importMap);
	}

	/**
	 * Handles MethodElement type changes. Note: for MethodElement objects in importMap
	 * only eClass type is used in this method.
	 */
	public static void handleTypeChanges(HashMap baseMap, HashMap importMap) {
		ArrayList toChangeList = new ArrayList();
		for (Iterator it = importMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			Object guid = entry.getKey();
			MethodElement baseElem = (MethodElement) baseMap.get(guid);
			if (baseElem != null) {
				MethodElement elem = (MethodElement) entry.getValue();
				if (! elem.eClass().equals(baseElem.eClass())) {
					MethodElement elemPair[] = new MethodElement[] {baseElem, elem};
					toChangeList.add(elemPair);
				}
			}			
		}
		for (int i=0; i<toChangeList.size(); i++) {
			MethodElement elemPair[] = (MethodElement[]) toChangeList.get(i);
			final MethodElement baseElem = elemPair[0];
			final MethodElement importElem = elemPair[1];
			if (baseElem instanceof Guidance) {
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						ConvertGuidanceType.convertGuidance((Guidance) baseElem, MsgBox.getDefaultShell(), null, importElem.eClass());
					}
				});
			} else if (baseElem instanceof Activity) {
				TypeConverter.convertActivity((Activity) baseElem, importElem.eClass()); 
			}
		}
	}

	/**
	 * Collects elements in lib that may have type changes 
	 */
	public static void collectPotentialTypeChanged(MethodLibrary lib, HashMap map) {
		for (Iterator it = lib.eAllContents(); it.hasNext();) {
			Object obj = it.next();
			if (obj instanceof Guidance ||
				obj instanceof Activity) {
				MethodElement elem = (MethodElement) obj;
				map.put(elem.getGuid(), elem);
			}
		}
	}
	
	public static boolean handleToolVersion(File libFile, final UpgradeCallerInfo info) {
		final String libFolderPath = libFile.getParentFile().getAbsolutePath();
		final boolean ret[] = new boolean[1];
		SafeUpdateController.syncExec(new Runnable() {	
			public void run() {
				ret[0] = OpenLibraryWizard.handleToolVersion(libFolderPath, info);
			}
		});								
		return ret[0];
	}	

	public static class UpgradeInfo extends UpgradeCallerInfo {
		
		public UpgradeInfo(int callerType, File libFile) {
			super(callerType, libFile);
		}
		
		public void copyLibrary() {
			String userHome = System.getProperty("user.home"); //$NON-NLS-1$
			String desLibFolderPath = userHome + File.separator
					+ "EPF" + File.separator + "Export" + File.separator //$NON-NLS-1$ //$NON-NLS-2$
					+ Long.toHexString(Calendar.getInstance().getTimeInMillis()) + File.separator;		
			File desLibFolder = new File(desLibFolderPath);
			if (!desLibFolder.exists()) {
				desLibFolder.mkdirs();
			} else {
				FileUtil.deleteAllFiles(desLibFolder.getAbsolutePath());
			}
			
			PluginExportService.copyDir(getLibFile().getParentFile(), desLibFolder);
			setCopiedLibFile(new File(desLibFolderPath + getLibFile().getName()));
		}
		
		public void removeCopiedLibrary() {
			if (getCopiedLibFile() == null) {
				return;
			}
			FileUtil.deleteAllFiles(getCopiedLibFile().getParentFile().getAbsolutePath());
			getCopiedLibFile().getParentFile().delete();
			setCopiedLibFile(null);
		}
	};	
	
}