//------------------------------------------------------------------------------
// 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 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.ui.LibraryUIImages;
import org.eclipse.epf.library.ui.wizards.LibraryBackupUtil;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.IFileManager;
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 = ContentDescriptionFactory.getFileManager();
		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
		// RATLC00386055 - 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;
		}

		ImportUIPreferences.setLastImportPluginPath(data.llData
				.getParentFolder());
		return true;
	}

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

}
