//------------------------------------------------------------------------------
// 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 org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.epf.common.serviceability.VersionUtil;
import org.eclipse.epf.export.services.LibraryDocument;
import org.eclipse.epf.importing.ImportPlugin;
import org.eclipse.epf.importing.ImportResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.project.MethodLibraryProject;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.ResourceUtil;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.osgi.util.NLS;


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

	private ConfigurationImportData data;

	LibraryDocument importingLibDoc = null;

	LibraryDiffManager diffMgr = null;

	ConfigSpecsImportManager specsMgr = null;
	
	public ConfigurationImportService(ConfigurationImportData data) {
		this.data = data;
	}

	
	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);
			if (!importingLibPath.exists()) {
				importingLibPath = new File(importingLibPath.getParentFile(),
						LibraryDocument.exportFile);
			}

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

			importingLibDoc = new LibraryDocument(importingLibPath);
			
			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 {
				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();
				MethodLibraryProject.openProject(libDir, monitor);
				try {
					MethodLibrary importLibraty = LibraryUtil
							.loadLibrary(importingLibPath.getAbsolutePath());
					MethodLibrary baseLibrary = LibraryService.getInstance()
							.getCurrentMethodLibrary();

					diffMgr = new LibraryDiffManager(baseLibrary, importLibraty);
					diffMgr.buildDiffTree();
				} catch (RuntimeException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				MethodLibraryProject.closeProject(libDir, monitor);
				
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

	public ConfigurationImportData getImportData() {
		return data;
	}

	public boolean isSpecsOnly() {
		return (data.specs != null);
	}

	public ElementDiffTree getDiffTree() {
		return diffMgr.getDiffTree();
	}

	public MethodLibrary getImportingLibrary() {
		return diffMgr.getImportingLibrary();
	}

	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);
			}		
		}	
		
		try {
			// Reopen the library.
			LibraryService.getInstance().reopenCurrentMethodLibrary();		

		} catch (Exception e) {
			ImportPlugin.getDefault().getLogger().logError(e);
		}
	}
	
	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),
						VersionUtil.FILETYPE_XMI);
				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];
	}
	
}