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

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.ui.util.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 {

	protected SelectImportPluginSource page1;

	protected SelectPluginsToImport page2;

	protected PluginImportData data = new PluginImportData();

	protected PluginImportingService service = new PluginImportingService(data);

	/**
	 * Creates a new instance.
	 */
	public ImportPluginWizard() {
		setWindowTitle(ImportResources.importPluginsWizard_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(
					ImportResources.importPluginsWizard_title,
					ImportResources.ImportPluginWizard_readonly);
			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);

			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(
							ImportResources.importPluginsWizard_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;
			boolean yes = ImportPlugin.getDefault().getMsgDialog()
					.displayConfirmation(
							ImportResources.importPluginsWizard_title, message);
			if (!yes) {
				return false;
			}
		}

		// Prompt user to back up library.
		LibraryBackupUtil.promptBackupCurrentLibrary(null, LibraryService
				.getInstance());
		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException {
				try {
					monitor.beginTask(ImportResources.ImportPluginWizard_MSG1,
							IProgressMonitor.UNKNOWN);

					// 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, 
					realException.getMessage());
			return false;
		}

		try {
			checkPluginCircularDependency();
		} catch (Throwable e) {
			e.printStackTrace();
		}

		// Save the import path to preference store.
		ImportUIPreferences.addImportPluginDir(data.llData.getParentFolder());

		ImportUIPreferences.setCheckBasePlugins(service.isCheckBasePlugins());
		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
					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()) {
						modifyInfo.readonlyPlugins.add(plugin);
					}
				}
			}
		}

		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);
		}
	}

}