/*=============================================================================#
 # Copyright (c) 2005, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.wizards;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.ContainerGenerator;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;

import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
import org.eclipse.statet.ltk.ui.util.LTKWorkbenchUIUtil;


public abstract class NewElementWizard extends Wizard implements INewWizard, IExecutableExtension {
	
	
	protected class NewProject {
		
		private final IProject project;
		
		/** Path of project, null for default location */
		protected IPath locationPath;
		
		private final IProject[] refProjects;
		
		private final IWorkingSet[] workingSets;
		
		
		public NewProject(final IProject project, final IPath location,
				final IProject[] refProjects, final IWorkingSet[] workingSets) {
			this.project= project;
			this.locationPath= location;
			this.refProjects= refProjects;
			this.workingSets= workingSets;
		}
		
		
		/**
		 * Returns a project resource handle.
		 * <p>
		 * Note: Handle is cached. This method does not create the project resource;
		 * this is the responsibility of <code>IProject::create</code>.
		 * </p>
		 * 
		 * @return the project resource handle
		 */
		public IProject getResource() {
			return this.project;
		}
		
		/**
		 * Creates the new project resource.
		 * <p>
		 * In normal usage, this method is invoked after the user has pressed Finish
		 * on the wizard; the enablement of the Finish button implies that all
		 * controls on the pages currently contain valid values.
		 * </p>
		 * @return the created project resource, or <code>null</code> if the
		 *     project was not created
		 * @throws CoreException
		 */
		public IProject createProject(final IProgressMonitor monitor)
				throws InvocationTargetException, InterruptedException, CoreException {
			final SubMonitor m= SubMonitor.convert(monitor, LTKWizardsMessages.NewElement_CreateProject_task, 20 + 2);
			
			final IWorkspace workspace= ResourcesPlugin.getWorkspace();
			final IProjectDescription description= workspace.newProjectDescription(this.project.getName());
			description.setLocation(this.locationPath);
			
			// update the referenced project if provided
			if (this.refProjects != null && this.refProjects.length > 0) {
				description.setReferencedProjects(this.refProjects);
			}
			
			if (monitor.isCanceled()) {
				throw new OperationCanceledException();
			}
			doCreateProject(this.project, description, m.newChild(10));
			doConfigProject(this.project, m.newChild(10));
			
			doAddToWorkingSets(this.project, m.newChild(2));
			
			return this.project;
		}
		
		private void doCreateProject(final IProject project, final IProjectDescription description,
				final SubMonitor m)
				throws CoreException {
			// run the new project creation operation
			m.beginTask("Install Project", 20); //$NON-NLS-1$
			
			project.create(description, m.newChild(10));
			if (m.isCanceled()) {
				throw new OperationCanceledException();
			}
			project.open(m.newChild(10));
			if (m.isCanceled()) {
				throw new OperationCanceledException();
			}
		}
		
		protected void doConfigProject(final IProject project, final IProgressMonitor monitor) throws CoreException {
		}
		
		private void doAddToWorkingSets(final IProject project, final IProgressMonitor monitor) {
			if (this.workingSets != null && this.workingSets.length > 0) {
				monitor.beginTask(LTKWizardsMessages.NewElement_AddProjectToWorkingSet_task, 1);
				getWorkbench().getWorkingSetManager().addToWorkingSets(project, this.workingSets);
			}
			monitor.done();
		}
		
	}
	
	protected static class NewContainer {
		
		
		private final IContainer container;
		
		
		public NewContainer(final IContainer container) {
			this.container= container;
		}
		
		public NewContainer(final IPath path) {
			this.container= (path.segmentCount() == 1) ?
					ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)) :
					ResourcesPlugin.getWorkspace().getRoot().getFolder(path);
		}
		
		
		/**
		 * Returns a container resource handle.
		 * <p>
		 * 
		 * @return the project resource handle
		 */
		public IContainer getResource() {
			return this.container;
		}
		
		protected void createFolder(IContainer container,
				final SubMonitor m) throws CoreException {
			if (container.getType() == IResource.FOLDER && !container.exists()) {
				final List<IFolder> toCreate= new ArrayList<>();
				do {
					toCreate.add((IFolder) container);
				} while ((container= container.getParent()).getType() == IResource.FOLDER
						&& !container.exists());
				m.setWorkRemaining(toCreate.size());
				for (int i= toCreate.size() - 1; i >= 0; i--) {
					toCreate.get(i).create(false, true, m.newChild(1));
				}
			}
		}
		
		/**
		 * Creates the new container resource.
		 * <p>
		 * In normal usage, this method is invoked after the user has pressed Finish
		 * on the wizard; the enablement of the Finish button implies that all
		 * controls on the pages currently contain valid values.
		 * </p>
		 * @return
		 * 
		 * @return the created project resource, or <code>null</code> if the
		 *     project was not created
		 * @throws CoreException
		 */
		public IContainer createContainer(
				final IProgressMonitor monitor) throws InterruptedException, CoreException {
			final SubMonitor m= SubMonitor.convert(monitor);
			
			final IContainer handle= getResource();
			createFolder(handle, m);
			
			return handle;
		}
		
		public IFolder createSubFolder(final IPath path,
				final IProgressMonitor monitor) throws InterruptedException, CoreException {
			final SubMonitor m= SubMonitor.convert(monitor);
			
			final IFolder handle= getResource().getFolder(path);
			
			createFolder(handle, m);
			
			return handle;
		}
		
	}
	
	protected static class NewFile {
		
		
		protected IPath containerPath;
		protected String resourceName;
		private IContentType contentType;
		protected IRegion initialSelection;
		
		/** No direct access, use getFileHandle() */
		private IFile cachedHandle;
		
		
		public NewFile(final IPath containerPath, final String resourceName) {
			this.containerPath= containerPath;
			this.resourceName= resourceName;
		}
		
		public NewFile(final IPath containerPath, final String resourceName,
				final IContentType contentType) {
			this(containerPath, resourceName);
			this.contentType= (contentType != null) ? contentType :
					Platform.getContentTypeManager().getContentType(IContentTypeManager.CT_TEXT);
		}
		
		
		/**
		 * Return the filehandle of the new file.
		 * The Filehandle is cached. File can exists or not exists.
		 * @return
		 */
		public IFile getResource() {
			if (this.cachedHandle == null) {
				final IPath fullPath= this.containerPath.append(this.resourceName);
				this.cachedHandle= createFileHandle(fullPath);
			}
			return this.cachedHandle;
		}
		
		/**
		 * Creates a file resource handle for the file with the given workspace path.
		 * This method does not create the file resource; this is the responsibility
		 * of <code>createFile</code>.
		 * 
		 * @param filePath the path of the file resource to create a handle for
		 * @return the new file resource handle
		 * @see #createFile
		 */
		protected IFile createFileHandle(final IPath filePath) {
			return ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
		}
		
		/**
		 * Creates a new file resource in the selected container and with the selected
		 * name. Creates any missing resource containers along the path; does nothing if
		 * the container resources already exist.
		 * <p>
		 * In normal usage, this method is invoked after the user has pressed Finish on
		 * the wizard; the enablement of the Finish button implies that all controls on
		 * on this page currently contain valid values.
		 * </p>
		 * <p>
		 * Note that this page caches the new file once it has been successfully
		 * created; subsequent invocations of this method will answer the same
		 * file resource without attempting to create it again.
		 * </p>
		 * <p>
		 * This method should be called within a workspace modify operation since
		 * it creates resources.
		 * </p>
		 * 
		 * @return the created file resource, or <code>null</code> if the file
		 *    was not created
		 * @throws InterruptedException
		 * @throws InvocationTargetException
		 * @throws CoreException
		 */
		public void createFile(final IProgressMonitor monitor)
				throws InvocationTargetException, InterruptedException, CoreException {
			final IPath containerPath= this.containerPath;
			final IFile newFileHandle= getResource();
			assert (containerPath != null);
			assert (newFileHandle != null);
			
			try {
				final SubMonitor m= SubMonitor.convert(monitor,
						NLS.bind(LTKWizardsMessages.NewElement_CreateFile_task, newFileHandle.getName()),
						1 + 1 + 3 );
				
				final InputStream initialContents= getInitialFileContentStream(newFileHandle,
						m.newChild(1) );
				
				final ContainerGenerator generator= new ContainerGenerator(containerPath);
				generator.generateContainer(m.newChild(1));
				doCreateFile(newFileHandle, initialContents, m.newChild(3));
			}
			finally {
				monitor.done();
			}
		}
		
		/**
		 * Creates a file resource given the file handle and contents.
		 * 
		 * @param fileHandle the file handle to create a file resource with
		 * @param contents the initial contents of the new file resource, or
		 *   <code>null</code> if none (equivalent to an empty stream)
		 * @param m the progress monitor to show visual progress with
		 * @exception CoreException if the operation fails
		 * @exception OperationCanceledException if the operation is canceled
		 */
		private static void doCreateFile(final IFile fileHandle, InputStream contents,
				final SubMonitor m) throws CoreException {
			if (contents == null) {
				contents= new ByteArrayInputStream(new byte[0]);
			}
			try {
				m.beginTask(null, 10 + 20);
				
				// Create a new file resource in the workspace
				final IPath path= fileHandle.getFullPath();
				final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
				final int numSegments= path.segmentCount();
				if (numSegments > 2 && !root.getFolder(path.removeLastSegments(1)).exists()) {
					final SubMonitor m1= m.newChild(10);
					// If the direct parent of the path doesn't exist, try to create the
					// necessary directories.
					for (int i= numSegments - 2; i > 0; i--) {
						m1.setWorkRemaining(i);
						final IFolder folder= root.getFolder(path.removeLastSegments(i));
						if (!folder.exists()) {
							folder.create(false, true, m1.newChild(1));
						}
						m1.worked(1);
					}
				}
				
				if (m.isCanceled()) {
					throw new OperationCanceledException();
				}
				m.setWorkRemaining(20);
				fileHandle.create(contents, false, m.newChild(20));
				
				if (m.isCanceled()) {
					throw new OperationCanceledException();
				}
			}
			catch (final CoreException e) {
				// If the file already existed locally, just refresh to get contents
				if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) {
					fileHandle.refreshLocal(IResource.DEPTH_ZERO, null);
				}
				else {
					throw e;
				}
			}
			
		}
		
		/**
		 * Returns a stream containing the initial contents to be given to new file resource
		 * instances.  <b>Subclasses</b> may wish to override.  This default implementation
		 * provides no initial contents.
		 * @param subMonitor 
		 * 
		 * @return initial contents to be given to new file resource instances
		 */
		protected InputStream getInitialFileContentStream(final IFile newFileHandle,
				final SubMonitor m) {
			final String content= getInitialFileContent(newFileHandle, m);
			if (content == null) {
				return null;
			}
			try {
				// encoding of content type
				final IContentType contentType= getContentType(newFileHandle);
				if (contentType != null) {
					final String charset= contentType.getDefaultCharset();
					if (charset != null) {
						return new ByteArrayInputStream(content.getBytes(charset));
					}
				}
				// encoding of container
				final String charset= newFileHandle.getCharset(true);
				if (charset != null) {
					return new ByteArrayInputStream(content.getBytes(charset));
				}
			}
			catch (final UnsupportedEncodingException | CoreException e) {
			}
			return new ByteArrayInputStream(content.getBytes());
		}
		
		/**
		 * Returns the content type of the new file.
		 * Used e.g. to lookup the encoding.
		 * @return id
		 */
		public IContentType getContentType(final IFile newFileHandle) {
			return this.contentType;
		}
		
		/**
		 * Returns a stream containing the initial contents to be given to new file resource
		 * instances.  <b>Subclasses</b> may wish to override.  This default implementation
		 * provides no initial contents.
		 * @param m 
		 * 
		 * @return initial contents to be given to new file resource instances
		 */
		protected String getInitialFileContent(final IFile newFileHandle,
				final SubMonitor m) {
			return null;
		}
		
		public IRegion getInitialSelection() {
			return this.initialSelection;
		}
		
	}
	
	
	private IWorkbench workbench;
	private IStructuredSelection selection;
	
	private IConfigurationElement configElement;
	
	
	public NewElementWizard() {
		setNeedsProgressMonitor(true);
	}
	
	/**
	 * Stores the configuration element for the wizard. The config element will
	 * be used in <code>performFinish</code> to set the result perspective.
	 */
	@Override
	public void setInitializationData(final IConfigurationElement config, final String propertyName, final Object data) {
		this.configElement= config;
	}
	
	
	/**
	 * Subclasses should override to perform the actions of the wizard.
	 * This method is run in the wizard container's context as a workspace runnable.
	 * @param monitor
	 * @throws InterruptedException
	 * @throws CoreException
	 * @throws InvocationTargetException
	 */
	protected abstract void performOperations(IProgressMonitor monitor) throws InterruptedException, CoreException, InvocationTargetException;
	
	/**
	 * @return the scheduling rule for creating the element.
	 */
	protected ISchedulingRule getSchedulingRule() {
		return ResourcesPlugin.getWorkspace().getRoot(); // lock all by default
	}
	
	/**
	 * @return true if the runnable should be run in a separate thread, and false to run in the same thread
	 */
	protected boolean canRunForked() {
		return true;
	}
	
//	public abstract IJavaElement getCreatedElement();
	
	
	@Override
	public void init(final IWorkbench workbench, final IStructuredSelection currentSelection) {
		this.workbench= workbench;
		this.selection= currentSelection;
	}
	
	@Override
	public boolean performFinish() {
		final WorkspaceModifyOperation op= new WorkspaceModifyOperation(getSchedulingRule()) {
			@Override
			protected void execute(final IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
				try {
					performOperations(monitor);
				}
				catch (final InterruptedException e) {
					throw new OperationCanceledException(e.getMessage());
				}
				catch (final CoreException e) {
					throw new InvocationTargetException(e);
				}
				finally {
					if (monitor != null) {
						monitor.done();
					}
				}
			}
		};
		try {
			getContainer().run(canRunForked(), true, op);
			return true;
		}
		catch (final InvocationTargetException e) {
			handleTasksException(getShell(), e);
			return false;
		}
		catch (final InterruptedException e) {
			return false;
		}
	}
	
	protected void handleTasksException(final Shell shell, final InvocationTargetException e) {
		StatusManager.getManager().handle(new Status(IStatus.ERROR, LTKUIPlugin.BUNDLE_ID, -1,
				LTKWizardsMessages.NewElement_error_DuringOperation_message, e),
				StatusManager.LOG | StatusManager.SHOW);
	}
	
	
	public IStructuredSelection getSelection() {
		return this.selection;
	}
	
	public IWorkbench getWorkbench() {
		return this.workbench;
	}
	
	
/* Helper methods for subclasses **********************************************/
	
	/**
	 * Returns the scheduling rule to use when creating the resource at
	 * the given container path. The rule should be the creation rule for
	 * the top-most non-existing parent.
	 * @param resource The resource being created
	 * @return The scheduling rule for creating the given resource
	 */
	protected ISchedulingRule createRule(IResource resource) {
		IResource parent= resource.getParent();
		while (parent != null) {
			if (parent.exists()) {
				return resource.getWorkspace().getRuleFactory().createRule(resource);
			}
			resource= parent;
			parent= parent.getParent();
		}
		return resource.getWorkspace().getRoot();
	}
	
	protected void openResource(final IFile resource) {
		final IWorkbenchPage activePage= UIAccess.getActiveWorkbenchPage(true);
		if (activePage != null) {
			LTKWorkbenchUIUtil.openEditor(activePage, resource, null);
		}
	}
	
	protected void openResource(final NewFile file) {
		if (file.getResource() == null) {
			return;
		}
		final IWorkbenchPage activePage= UIAccess.getActiveWorkbenchPage(true);
		if (activePage != null) {
			LTKWorkbenchUIUtil.openEditor(activePage, file.getResource(), file.getInitialSelection());
		}
	}
	
	protected void selectAndReveal(final IResource newResource) {
		BasicNewResourceWizard.selectAndReveal(newResource, this.workbench.getActiveWorkbenchWindow());
	}
	
	protected void updatePerspective() {
		BasicNewProjectResourceWizard.updatePerspective(this.configElement);
	}
	
}
