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

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.epf.authoring.ui.wizards.SaveAllEditorsPage;
import org.eclipse.epf.common.serviceability.MsgBox;
import org.eclipse.epf.importing.ImportPlugin;
import org.eclipse.epf.importing.ImportResources;
import org.eclipse.epf.importing.services.PluginImportData;
import org.eclipse.epf.importing.services.PluginImportingService;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.PluginDepInfo;
import org.eclipse.epf.library.edit.validation.PluginDependencyInfoMgr;
import org.eclipse.epf.library.ui.LibraryUIImages;
import org.eclipse.epf.library.ui.wizards.LibraryBackupUtil;
import org.eclipse.epf.services.IFileManager;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IImportWizard;
import org.eclipse.ui.IWorkbench;

/**
 * A wizard that imports an exported method plug-ins into the currrent method
 * library.
 * 
 * @author Jeff Hardy
 * @author Kelvin Low
 * @since 1.0
 */
public class ImportPluginWizard extends Wizard implements IImportWizard {

	private static final String WIZARD_TITLE = ImportResources.importPluginsWizard_title; //$NON-NLS-1$

	protected SelectImportPluginSource page1;

	protected SelectPluginsToImport page2;

	protected PluginImportData data = new PluginImportData();

	protected PluginImportingService service = new PluginImportingService(data);

	/**
	 * Creates a new instance.
	 */
	public ImportPluginWizard() {
		setWindowTitle(WIZARD_TITLE);
		setNeedsProgressMonitor(true);
	}

	/**
	 * @see org.eclipse.ui.IWorkbenchWizard#init(IWorkbench,
	 *      IStructuredSelection)
	 */
	public void init(IWorkbench workbench, IStructuredSelection selection) {
	}

	/**
	 * @see org.eclipse.jface.wizard.Wizard#addPages()
	 */
	public void addPages() {
		// check out the library first
		IFileManager fileMgr = Services.getFileManager();
		if (LibraryService.getInstance()
				.getCurrentMethodLibrary() != null) {
			fileMgr.checkModify(LibraryService.getInstance()
					.getCurrentMethodLibrary().eResource().getURI().toFileString(),
					MsgBox.getDefaultShell());
		}
		ILibraryManager manager = (ILibraryManager) LibraryService
				.getInstance().getCurrentLibraryManager();
		if (manager != null && manager.isMethodLibraryReadOnly()) {
			ImportPlugin.getDefault().getMsgDialog().displayError(
					WIZARD_TITLE,
					ImportResources.ImportPluginWizard_readonly); //$NON-NLS-1$
			return;
		}

		SaveAllEditorsPage.addPageIfNeeded(this, true, null, null, ImportPlugin
				.getDefault().getImageDescriptor(
						"full/wizban/ImportMethodPlugins.gif")); //$NON-NLS-1$

		page1 = new SelectImportPluginSource(data, service);
		addPage(page1);

		page2 = new SelectPluginsToImport(data, service);
		addPage(page2);
	}

	/**
	 * @see org.eclipse.jface.wizard.Wizard#createPageControls(Composite)
	 */
	public void createPageControls(Composite pageContainer) {
		super.createPageControls(pageContainer);
		pageContainer.getShell().setImage(LibraryUIImages.IMG_METHOD_PLUGIN);
	}

	/**
	 * @see org.eclipse.jface.wizard.IWizard#canFinish()
	 */
	public boolean canFinish() {
		if (this.getContainer().getCurrentPage() != page2)
			return false;
		return page2.isPageComplete();
	}

	/**
	 * @see org.eclipse.jface.wizard.IWizard#performFinish()
	 */
	public boolean performFinish() {
		// Check if the selected plug-ins are updatable or not.
		PluginModifyInfo modifyInfo = checkModify();

		// if only locked, we can auto-unlock and relock the plugins
		// if the pluin is readonly, user need to manually make it updatable
		// customers need to manually unlock and lock plugins
		// during content library upgrade

		if (modifyInfo.readonlyPlugins.size() > 0) {
			// Display an error message.
			String error = modifyInfo.getReadonlyMessage().toString();
			ImportPlugin
					.getDefault()
					.getMsgDialog()
					.displayError(
							ImportResources.ImportConfigurationWizard_error, error); //$NON-NLS-1$

			return false;
		}

		StringBuffer buffer = new StringBuffer();
		PluginImportData.PluginInfo info;
		for (Iterator it = data.getPlugins().iterator(); it.hasNext();) {
			info = (PluginImportData.PluginInfo) it.next();
			if ((info.existingPlugin != null) && info.selected) {
				if (buffer.length() > 0) {
					buffer.append("\n"); //$NON-NLS-1$
				}
				buffer.append("\t").append(info.name); //$NON-NLS-1$
			}
		}

		if (buffer.length() > 0) {
			boolean yes = ImportPlugin
					.getDefault()
					.getMsgDialog()
					.displayConfirmation(
							WIZARD_TITLE,
							NLS.bind(ImportResources.ImportPluginWizard_warn_existing_plugins, buffer.toString()));

			if (!yes) {
				return false;
			}
		}

		// allow user to proceed with locked plugins
		if (modifyInfo.lockedPlugins.size() > 0) {
			String message = modifyInfo.getLockedMessage().toString()
					+ ImportResources.ImportPluginWizard_confirm_continue; //$NON-NLS-1$
			boolean yes = ImportPlugin.getDefault().getMsgDialog()
					.displayConfirmation(WIZARD_TITLE, message);
			if (!yes) {
				return false;
			}
		}

		// Prompt user to back up library.
		LibraryBackupUtil.promptBackupLibrary(null, new File(LibraryService
				.getInstance().getCurrentMethodLibraryPath()));
		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException {
				try {
					monitor
							.beginTask(
									ImportResources.ImportPluginWizard_MSG1, IProgressMonitor.UNKNOWN); //$NON-NLS-1$

					// Start the import.
					service.performImport(monitor);
				} catch (Exception e) {
					throw new InvocationTargetException(e);
				} finally {
					monitor.done();
				}
			}
		};

		try {
			getContainer().run(true, false, op);
		} catch (InterruptedException e) {
			return false;
		} catch (InvocationTargetException e) {
			Throwable realException = e.getTargetException();
			ImportPlugin.getDefault().getMsgDialog().displayError(
					ImportResources.ImportPluginWizard_error, //$NON-NLS-1$
					realException.getMessage());
			return false;
		}

		try {
			checkPluginCircularDependency();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		
//		record the opened dir into preference store
		ImportUIPreferences.addRecentlyImportPluginDir(data.llData
				.getParentFolder());
		return true;
	}

	/**
	 * Returns a PluginModifyInfo object.
	 */
	public PluginModifyInfo checkModify() {
		// StringBuffer error = new StringBuffer();
		PluginModifyInfo modifyInfo = new PluginModifyInfo();

		PluginImportData.PluginInfo info;
		for (Iterator it = data.getPlugins().iterator(); it.hasNext();) {
			info = (PluginImportData.PluginInfo) it.next();
			MethodPlugin plugin = info.existingPlugin;
			if ((plugin != null) && info.selected) {
				if (plugin.getUserChangeable().booleanValue() == false) {
					// The plug-in is locked
					// String msg = ImportResources
					// .getString(
					// "Import.SelectImportConfigurationSource.plugin_locked",
					// plugin.getName()); //$NON-NLS-1$
					// error.append(msg);
					modifyInfo.lockedPlugins.add(plugin);
				} else {
					// The plug-in exists in the current library, make sure the
					// plug-in is updatable.
					IStatus status = TngUtil.checkEdit(plugin, getShell());
					if (!status.isOK()) {
						// String msg = ImportResources
						// .getString(
						// "Import.SelectImportConfigurationSource.plugin_readonly",
						// plugin.getName()); //$NON-NLS-1$
						// error.append(msg);
						modifyInfo.readonlyPlugins.add(plugin);
					}
				}
			}
		}

		// modifyInfo.message = error.toString();

		return modifyInfo;
	}
	
	private void checkPluginCircularDependency() {
		PluginDependencyInfoMgr mgr = new PluginDependencyInfoMgr(LibraryService.getInstance().getCurrentMethodLibrary());
		PluginDependencyInfoMgr.CheckResult result = mgr.checkCircularDependnecy(null, false);
		if (result.circularList != null && !result.circularList.isEmpty()) {
			List cirPlugins = (List) result.circularList.get(0);
			String msg = "";	//$NON-NLS-1$
			for (int i=0; i<cirPlugins.size(); i++) {
				PluginDepInfo pinfo = (PluginDepInfo) cirPlugins.get(i);
				if (i != 0) {
					msg += ", "; 						//$NON-NLS-1$
				}
				msg += pinfo.getPlugin().getName();
			}
			ImportPlugin.getDefault().getMsgDialog().displayWarning(
					ImportResources.ImportPluginWizard_warn_circular_plugins, 
					msg);	
		}
	}

}