/*******************************************************************************
* Copyright (c) 2010 Oracle. 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:
*     Oracle - initial API and implementation
*******************************************************************************/
package org.eclipse.jpt.jaxb.ui.internal.wizards.schemagen;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jpt.jaxb.core.internal.SchemaGenerator;
import org.eclipse.jpt.jaxb.ui.JptJaxbUiIcons;
import org.eclipse.jpt.jaxb.ui.JptJaxbUiPlugin;
import org.eclipse.jpt.jaxb.ui.internal.JptJaxbUiMessages;
import org.eclipse.jpt.jaxb.ui.internal.wizards.ProjectWizardPage;
import org.eclipse.jpt.utility.internal.ArrayTools;
import org.eclipse.jpt.utility.internal.FileTools;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IExportWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;

public class SchemaGeneratorWizard extends Wizard implements IExportWizard {

	protected IStructuredSelection selection;

	private ProjectWizardPage javaProjectWizardPage;
	protected SchemaGeneratorWizardPage schemaGenWizardPage;

	public static final String XSD_EXTENSION = ".xsd";   //$NON-NLS-1$
	
	// ********** constructor **********
	
	public SchemaGeneratorWizard() {
		super();
	}

	// ********** IWorkbenchWizard implementation  **********
	
	public void init(IWorkbench workbench, IStructuredSelection selection) {

		this.selection = this.getValidSelection();
		
		this.setWindowTitle(JptJaxbUiMessages.SchemaGeneratorWizard_title);
		this.setDefaultPageImageDescriptor(JptJaxbUiPlugin.getImageDescriptor(JptJaxbUiIcons.SCHEMA_GEN_WIZ_BANNER));
		this.setNeedsProgressMonitor(true);
	}

	// ********** IWizard implementation  **********

	@Override
	public void addPages() {
		super.addPages();
		if(this.selection.isEmpty()) {
			this.javaProjectWizardPage = new ProjectWizardPage();
			this.javaProjectWizardPage.setTitle(JptJaxbUiMessages.SchemaGeneratorProjectWizardPage_title);
			this.addPage(this.javaProjectWizardPage);
		}

		this.schemaGenWizardPage = new SchemaGeneratorWizardPage(this.selection);
		this.addPage(this.schemaGenWizardPage);
	}
	
	@Override
	public boolean performFinish() {

		IJavaProject javaProject = this.getJavaProject();
		
		String[] sourceClassNames = this.buildSourceClassNames(this.getAllCheckedItems());
		
		WorkspaceJob genSchemaJob = new GenerateSchemaJob( 
						javaProject, 
						sourceClassNames, 
						this.getTargetSchema(), 
						this.usesMoxy());
		genSchemaJob.schedule();

		return true;
	}

	// ********** internal methods **********
	
	private String getTargetSchema() {
		String targetSchema = this.schemaGenWizardPage.getSchemaPath();
		if ( ! FileTools.extension(targetSchema).equalsIgnoreCase(XSD_EXTENSION)) {
			targetSchema += XSD_EXTENSION;
		}
		return targetSchema;
	}
	
	private IJavaProject getJavaProject() {
		return this.schemaGenWizardPage.getJavaProject();
	}
	
	private boolean usesMoxy() {
		return this.schemaGenWizardPage.usesMoxy();
	}

	private Object[] getAllCheckedItems() {
		return this.schemaGenWizardPage.getAllCheckedItems();
	}
	
	private String[] buildSourceClassNames(Object[] checkedElements) {

		ArrayList<String> classNames = new ArrayList<String>();
		
		for(Object element: checkedElements) {
			IJavaElement javaElement = (IJavaElement)element;
			String packageName = javaElement.getParent().getElementName();
			String elementName = javaElement.getElementName();
			String className = FileTools.stripExtension(elementName);
			classNames.add(packageName + '.' + className);
		}
		
		return ArrayTools.array(classNames, new String[0]);
	}
	
	/**
	 * Gets the current workspace page selection and converts it to a valid
	 * selection for this wizard.
	 * Valid selections: 
	 *      - Java projects
	 *      - Source package fragments
	 *  all other input elements are ignored
	 *
	 * @return a valid structured selection based on the current selection
	 */
	private IStructuredSelection getValidSelection() {
		ISelection currentSelection = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection();
		if(currentSelection instanceof IStructuredSelection) {
			IStructuredSelection structuredSelection = (IStructuredSelection) currentSelection;
			List<IAdaptable> selectedElements = new ArrayList<IAdaptable>(structuredSelection.size());
			Iterator<?> i = structuredSelection.iterator();
			while(i.hasNext()) {
				Object selectedElement = i.next();
				if(selectedElement instanceof IProject) {
					this.addProject(selectedElements, (IProject)selectedElement);
				}
				else if(selectedElement instanceof IJavaElement) {
					this.addJavaElement(selectedElements, (IJavaElement)selectedElement);
				}
			}
			return new StructuredSelection(selectedElements);
		} 
		return StructuredSelection.EMPTY;
	}

	private void addJavaElement(List<IAdaptable> selectedElements, IJavaElement javaElement) {
		if(javaElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
			if( ! isInArchiveOrExternal(javaElement))
				selectedElements.add(javaElement);
		} 
	}

	private void addProject(List<IAdaptable> selectedElements, IProject project) {
		try {
			if(project.hasNature(JavaCore.NATURE_ID))
				selectedElements.add(JavaCore.create(project));
		} 
		catch(CoreException ex) {
			// ignore selected element
		}
	}

	private static boolean isInArchiveOrExternal(IJavaElement element) {
		IPackageFragmentRoot root = (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
		return root != null && (root.isArchive() || root.isExternal());
	}
	
	// ********** generate schema job **********

	static class GenerateSchemaJob extends WorkspaceJob {
		private final IJavaProject javaProject;
		private final String[] sourceClassNames;
		private final String targetSchema;
		private final boolean useMoxy;
		
		GenerateSchemaJob(IJavaProject project, String[] sourceClassNames, String targetSchema, boolean useMoxy) {
			super(JptJaxbUiMessages.SchemaGeneratorWizard_generatingSchema);
			
			this.javaProject = project ;
			this.sourceClassNames = sourceClassNames;
			this.targetSchema = targetSchema;
			this.useMoxy = useMoxy;

			this.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(this.javaProject.getProject()));
		}

		@Override
		public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
			SubMonitor sm = SubMonitor.convert(monitor, NLS.bind(JptJaxbUiMessages.SchemaGeneratorWizard_generateSchemaTask, this.targetSchema), 1);
			try {
				SchemaGenerator.generate(this.javaProject, this.targetSchema, this.sourceClassNames, this.useMoxy, sm.newChild(1));
			}
			catch (OperationCanceledException e) {
				return Status.CANCEL_STATUS;
			}
			return Status.OK_STATUS;
		}
	}
}