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

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

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.export.ExportResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;

/**
 * Exports one or more method plug-ins to a target directory.
 * 
 * @author Jinhua Xi
 * @author Kelvin Low
 * @since 1.0
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=162153
 */
public class PluginExportService extends BaseExportService {

	PluginExportData data;

	/**
	 * Creates a new instance.
	 */
	public PluginExportService(PluginExportData data) {
		this.data = data;
	}

	/**
	 * Run to export plugins
	 */
	public void run(IProgressMonitor monitor) {
		monitor.setTaskName(ExportResources.PluginExportService_MSG0); 

		List plugins = data.selectedPlugins;
		if (plugins == null || plugins.size() == 0) {
			return;
		}

		monitor.setTaskName(ExportResources.PluginExportService_MSG1); 

		// Create the library folder in the target directory.
		String exportLibPath = (new File(data.llData.getParentFolder())).getAbsolutePath();
		File exportLibFolder = new File(exportLibPath);
		if (!exportLibFolder.exists()) {
			exportLibFolder.mkdir();
		}

		monitor.setTaskName(ExportResources.PluginExportService_MSG2); 

		MethodLibrary currLib = LibraryService.getInstance().getCurrentMethodLibrary();
		String currLibPath = currLib.eResource().getURI().toFileString();
		File currLibFile = new File(currLibPath);
		
		// Iterate the selected plug-ins and copy their associated model files.
		for (Iterator it = plugins.iterator(); it.hasNext();) {
			MethodPlugin plugin = (MethodPlugin) it.next();
			if (plugin == null) {
				continue;
			}

			// Step 1: Create the plug-in folder.
			URI uri = plugin.eResource().getURI();
			String path = uri.toFileString();

			File pluginFolder = (new File(path)).getParentFile();

			String pluginPath = plugin.getName() + File.separator;
			File exportPluginFolder = new File(exportLibFolder, pluginPath);

			// Step 2: Copy the plug-in files.
			copyDir(pluginFolder, exportPluginFolder);			
		}

		monitor.setTaskName(ExportResources.PluginExportService_MSG3); 

		// Get the selected plug-in and configuration ids so we can remove the
		// unneeded stuff.
		getSelectedIds(data.selectedPlugins, data.associatedConfigMap);

		// Step 3: Load the library.xmi and the resmgr.xmi, remove the unneeded
		// stuff.
		File libFolder = new File(LibraryService.getInstance().getCurrentMethodLibraryLocation());
		LibraryDocument document = processLibraryFile(currLibFile, new File(
				exportLibFolder, exportFile));

		if ( document != null ) {
			// copy the conifuration files
			// 142379 - update plugin importing and exporting to match with the new file format
			copyConfigurationFiles(document, libFolder, exportLibFolder);
		}
		
		monitor.setTaskName(ExportResources.PluginExportService_MSG4); 
	}

	
	private void copyConfigurationFiles(LibraryDocument document, File libFolder, File exportLibFolder) {
		// // 142379 - update plugin importing and exporting to match with the new file format
		// Get the selected configuration ids.
		for (Iterator itc = data.associatedConfigMap.values().iterator(); itc.hasNext();) {
			List configs = (List) itc.next();
			if (configs == null || configs.size() == 0) {
				continue;
			}

			for (Iterator it = configs.iterator(); it.hasNext();) {
				MethodConfiguration config = (MethodConfiguration) it.next();
				String guid = config.getGuid();
				String uri = document.getResourceUri(guid);
				File src = null;
				if (uri == null) {
					URI resUri = config.eResource().getURI();
					uri = MultiFileSaveUtil.METHOD_CONFIGURATION_FOLDER_NAME + File.separator + resUri.lastSegment();
					uri = document.decodeUri(uri);
					src = new File(resUri.toFileString());
				}				
				if ( uri != null ) {
					//File src = new File(libFolder, uri);
					if (src == null) {
						src = new File(libFolder, uri);
					}
					File target =  new File(exportLibFolder, uri);
					FileUtil.copyFile(src, target);
				}
			}
		}
	}

	/**
	 * Copies directories from "fromDir" to "toDir".
	 */
	public static void copyDir(File fromDir, File toDir) {
		Copy cp = new Copy();
		cp.setOverwrite(true);
		FileSet set = new FileSet();
		set.setExcludes(ConfigurationExportService.excludes);
		set.setDir(fromDir);
		cp.addFileset(set);
		cp.setTodir(toDir);
		cp.setProject(new Project());
		cp.setPreserveLastModified(true);
		cp.execute();
	}

	private void getSelectedIds(List plugins, Map configsMap) {
		selectedIds.clear();
		selectedPluginNames.clear();

		// Get the plug-in ids and names.
		MethodPlugin plugin = null;
		for (Iterator it = plugins.iterator(); it.hasNext();) {
			plugin = (MethodPlugin) it.next();
			String guid = plugin.getGuid();
			selectedPluginNames.add(plugin.getName());
			if (!selectedIds.contains(guid)) {
				selectedIds.add(guid);
			}
		}

		// Save the library guid so that the entry in resgr.xmi will be kept.
		if (plugin != null) {
			MethodLibrary lib = (MethodLibrary) plugin.eContainer();
			if (lib != null) {
				selectedIds.add(lib.getGuid());
			}
		}

		// Get the selected configuration ids.
		for (Iterator itc = configsMap.values().iterator(); itc.hasNext();) {
			List configs = (List) itc.next();
			if (configs == null || configs.size() == 0) {
				continue;
			}

			for (Iterator it = configs.iterator(); it.hasNext();) {
				MethodConfiguration config = (MethodConfiguration) it.next();
				String guid = config.getGuid();
				if (selectedIds.contains(guid)) {
					continue;
				}

				// Add the configuration.
				selectedIds.add(guid);

				// For each configuration, save the method plug-in and package
				// ids so that their entries in the resource file can be kept.
				List refs = config.eCrossReferences();
				for (Iterator itr = refs.iterator(); itr.hasNext();) {
					Object o = itr.next();
					if (o instanceof MethodPlugin || o instanceof MethodPackage) {
						guid = ((MethodElement) o).getGuid();
						if (!selectedIds.contains(guid)) {
							selectedIds.add(guid);
						}
					} else {
						System.out
								.println("Unexpected element type '" + ((MethodElement) o).getType().getName() //$NON-NLS-1$
										+ "' in configuration '" + config.getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
			}
		}
	}

}
