/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Martin Karpisek (martin.karpisek@gmail.com) - bug 229474
 *******************************************************************************/
package org.eclipse.ant.internal.ui.datatransfer;

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

import org.apache.tools.ant.Task;
import org.apache.tools.ant.UnknownElement;
import org.apache.tools.ant.taskdefs.Javac;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.AntUtil;
import org.eclipse.ant.internal.ui.model.AntModelContentProvider;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.AntTargetNode;
import org.eclipse.ant.internal.ui.model.AntTaskNode;
import org.eclipse.ant.internal.ui.model.IAntElement;
import org.eclipse.ant.internal.ui.model.IAntModel;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;

public class AntNewJavaProjectPage extends WizardPage {

	private static class ImportOverwriteQuery implements IOverwriteQuery {
		@Override
		public String queryOverwrite(String file) {
			return ALL;
		}
	}

	private Text fProjectNameField;
	private Text fLocationPathField;
	private Button fBrowseButton;
	private Button fLinkButton;

	private IAntModel fAntModel;

	private ModifyListener fLocationModifyListener = new ModifyListener() {
		@Override
		public void modifyText(ModifyEvent e) {
			// no lexical or position, has task info
			fAntModel = AntUtil.getAntModel(getProjectLocationFieldValue(), false, false, true);
			AntProjectNode projectNode = fAntModel == null ? null : fAntModel.getProjectNode();
			if (fAntModel != null && projectNode != null) {
				setProjectName(); // page will be validated on setting the project name
				List<AntTaskNode> javacNodes = new ArrayList<>();
				getJavacNodes(javacNodes, projectNode);
				fTableViewer.setInput(javacNodes.toArray());
				if (!javacNodes.isEmpty()) {
					fTableViewer.setSelection(new StructuredSelection(javacNodes.get(0)));
				}
				fTableViewer.getControl().setEnabled(true);
			} else {
				fTableViewer.setInput(new Object[] {});
				fTableViewer.getControl().setEnabled(false);
			}
			setPageComplete(validatePage());
		}
	};

	private ModifyListener fNameModifyListener = new ModifyListener() {
		@Override
		public void modifyText(ModifyEvent e) {
			setPageComplete(validatePage());
		}
	};

	private static final int SIZING_TEXT_FIELD_WIDTH = 250;
	private TableViewer fTableViewer;

	public AntNewJavaProjectPage() {
		super("newPage"); //$NON-NLS-1$
		setPageComplete(false);
		setTitle(DataTransferMessages.AntNewJavaProjectPage_9);
		setDescription(DataTransferMessages.AntNewJavaProjectPage_10);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	public void createControl(Composite parent) {
		initializeDialogUnits(parent);
		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginHeight = IDialogConstants.VERTICAL_MARGIN;
		layout.marginWidth = IDialogConstants.HORIZONTAL_MARGIN;
		layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
		layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
		layout.numColumns = 3;
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		composite.setFont(parent.getFont());

		createProjectNameGroup(composite);
		createProjectLocationGroup(composite);
		createTargetsTable(composite);

		fLinkButton = new Button(composite, SWT.CHECK);
		fLinkButton.setText(DataTransferMessages.AntNewJavaProjectPage_24);
		fLinkButton.setFont(parent.getFont());
		GridData gd = new GridData();
		gd.horizontalAlignment = GridData.FILL;
		gd.grabExcessHorizontalSpace = false;
		gd.horizontalSpan = 2;
		fLinkButton.setLayoutData(gd);

		validatePage();
		// Show description on opening
		setErrorMessage(null);
		setMessage(null);
		setControl(composite);
	}

	/**
	 * Creates the project location specification controls.
	 * 
	 * @param parent
	 *            the parent composite
	 */
	private final void createProjectLocationGroup(Composite parent) {
		// new project label
		Label projectContentsLabel = new Label(parent, SWT.NONE);
		projectContentsLabel.setText(DataTransferMessages.AntNewJavaProjectPage_11);
		projectContentsLabel.setFont(parent.getFont());

		createUserSpecifiedProjectLocationGroup(parent);
	}

	/**
	 * Creates the project name specification controls.
	 * 
	 * @param parent
	 *            the parent composite
	 */
	private final void createProjectNameGroup(Composite parent) {

		Font dialogFont = parent.getFont();

		// new project label
		Label projectLabel = new Label(parent, SWT.NONE);
		projectLabel.setText(DataTransferMessages.AntNewJavaProjectPage_12);
		projectLabel.setFont(dialogFont);
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		projectLabel.setLayoutData(gd);

		// new project name entry field
		fProjectNameField = new Text(parent, SWT.BORDER);
		gd = new GridData();
		gd.horizontalAlignment = GridData.FILL;
		gd.grabExcessHorizontalSpace = false;
		gd.horizontalSpan = 2;
		fProjectNameField.setLayoutData(gd);
		fProjectNameField.setFont(dialogFont);

		fProjectNameField.addModifyListener(fNameModifyListener);
	}

	/**
	 * Creates the project location specification controls.
	 * 
	 * @param projectGroup
	 *            the parent composite
	 */
	private void createUserSpecifiedProjectLocationGroup(Composite projectGroup) {

		Font dialogFont = projectGroup.getFont();

		// project location entry field
		fLocationPathField = new Text(projectGroup, SWT.BORDER);
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		data.widthHint = SIZING_TEXT_FIELD_WIDTH;
		fLocationPathField.setLayoutData(data);
		fLocationPathField.setFont(dialogFont);

		// browse button
		fBrowseButton = new Button(projectGroup, SWT.PUSH);
		fBrowseButton.setText(DataTransferMessages.AntNewJavaProjectPage_13);
		fBrowseButton.setFont(dialogFont);
		setButtonLayoutData(fBrowseButton);

		fBrowseButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleBrowseButtonPressed();
			}
		});

		fLocationPathField.addModifyListener(fLocationModifyListener);
	}

	/**
	 * Returns the current project name
	 * 
	 * @return the project name
	 */
	private String getProjectName(AntProjectNode projectNode) {
		String projectName = projectNode.getLabel();
		if (projectName == null) {
			projectName = DataTransferMessages.AntNewJavaProjectPage_14;
		}
		return projectName;
	}

	/**
	 * Returns the value of the project name field with leading and trailing spaces removed.
	 * 
	 * @return the project name in the field
	 */
	private String getProjectNameFieldValue() {
		if (fProjectNameField == null) {
			return IAntCoreConstants.EMPTY_STRING;
		}
		return fProjectNameField.getText().trim();
	}

	/**
	 * Returns the value of the project location field with leading and trailing spaces removed.
	 * 
	 * @return the project location directory in the field
	 */
	private String getProjectLocationFieldValue() {
		return fLocationPathField.getText().trim();
	}

	/**
	 * Determine the buildfile the user wishes to operate from
	 */
	private void handleBrowseButtonPressed() {

		String lastUsedPath = IAntCoreConstants.EMPTY_STRING;
		FileDialog dialog = new FileDialog(getShell(), SWT.SINGLE | SWT.SHEET);
		dialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ ;
		dialog.setFilterPath(lastUsedPath);

		String result = dialog.open();
		if (result == null) {
			return;
		}
		IPath filterPath = new Path(dialog.getFilterPath());
		String buildFileName = dialog.getFileName();
		IPath path = filterPath.append(buildFileName).makeAbsolute();

		fLocationPathField.setText(path.toOSString());
	}

	/**
	 * Returns whether this page's controls currently all contain valid values.
	 * 
	 * @return <code>true</code> if all controls are valid, and <code>false</code> if at least one is invalid
	 */
	private boolean validatePage() {

		String locationFieldContents = getProjectLocationFieldValue();

		if (locationFieldContents.equals(IAntCoreConstants.EMPTY_STRING)) {
			setErrorMessage(null);
			setMessage(DataTransferMessages.AntNewJavaProjectPage_15);
			return false;
		}

		IPath path = new Path(IAntCoreConstants.EMPTY_STRING);
		if (!path.isValidPath(locationFieldContents)) {
			setErrorMessage(DataTransferMessages.AntNewJavaProjectPage_16);
			return false;
		}

		if (fAntModel == null) {
			if (getBuildFile(locationFieldContents) == null) {
				setErrorMessage(DataTransferMessages.AntNewJavaProjectPage_0);
				return false;
			}
			setErrorMessage(DataTransferMessages.AntNewJavaProjectPage_17);
			return false;
		}

		if (fAntModel.getProjectNode() == null) {
			setErrorMessage(DataTransferMessages.AntNewJavaProjectPage_2);
			return false;
		}

		if (getProjectNameFieldValue().length() == 0) {
			setErrorMessage(DataTransferMessages.AntNewJavaProjectPage_18);
			return false;
		}
		try {
			IProject existingProject = ResourcesPlugin.getWorkspace().getRoot().getProject(getProjectNameFieldValue());
			if (existingProject.exists()) {
				setErrorMessage(DataTransferMessages.AntNewJavaProjectPage_19);
				return false;
			}
		}
		catch (IllegalArgumentException e) {
			setErrorMessage(NLS.bind(DataTransferMessages.AntNewJavaProjectPage_23, e.getLocalizedMessage()));
			return false;
		}

		if (fTableViewer.getTable().getItemCount() == 0) {
			setErrorMessage(DataTransferMessages.AntNewJavaProjectPage_1);
			setPageComplete(false);
			return false;
		}

		setErrorMessage(null);
		setMessage(null);
		return true;
	}

	/**
	 * Set the project name using either the name of the parent of the file or the name entry in the xml for the file
	 */
	private void setProjectName() {
		AntProjectNode node = fAntModel.getProjectNode();
		String projectName = getProjectName(node);

		fProjectNameField.setText(projectName);
	}

	/**
	 * Return a .xml file from the specified location. If there isn't one return null.
	 */
	private File getBuildFile(String locationFieldContents) {
		File buildFile = new File(locationFieldContents);
		if (!buildFile.isFile() || !buildFile.exists()) {
			return null;
		}

		return buildFile;
	}

	/**
	 * Creates a new project resource based on the Ant buildfile. The classpath is configured based on the classpath of the javac declaration in the
	 * buildfile.
	 * 
	 * @return the created project resource, or <code>null</code> if the project was not created
	 */
	protected IJavaProject createProject() {
		final IJavaProject[] result = new IJavaProject[1];
		final String projectName = getProjectNameFieldValue();
		final File buildFile = getBuildFile(getProjectLocationFieldValue());
		final List<?> selectedJavacs = ((IStructuredSelection) fTableViewer.getSelection()).toList();
		final boolean link = fLinkButton.getSelection();
		WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
			@Override
			protected void execute(IProgressMonitor monitor) throws CoreException {
				List<?> javacTasks = resolveJavacTasks(selectedJavacs);
				ProjectCreator creator = new ProjectCreator();
				Iterator<?> iter = javacTasks.iterator();
				while (iter.hasNext()) {
					Javac javacTask = (Javac) iter.next();
					IJavaProject javaProject = creator.createJavaProjectFromJavacNode(projectName, javacTask, monitor);
					importBuildFile(monitor, javaProject, buildFile, link);
					result[0] = javaProject;
				}
			}
		};

		// run the new project creation operation
		try {
			getContainer().run(true, true, op);
		}
		catch (InterruptedException e) {
			return null;
		}
		catch (InvocationTargetException e) {
			// ie.- one of the steps resulted in a core exception
			Throwable t = e.getTargetException();
			IStatus status = null;
			if (t instanceof CoreException) {
				status = ((CoreException) t).getStatus();
			} else {
				status = new Status(IStatus.ERROR, AntUIPlugin.PI_ANTUI, IStatus.OK, "Error occurred. Check log for details ", t); //$NON-NLS-1$
				AntUIPlugin.log(t);
			}
			ErrorDialog.openError(getShell(), DataTransferMessages.AntNewJavaProjectPage_21, null, status);
		}

		return result[0];
	}

	protected void importBuildFile(IProgressMonitor monitor, IJavaProject javaProject, File buildFile, boolean link) {
		if (link) {
			IProject project = javaProject.getProject();
			IFile iBuildFile = project.getFile(buildFile.getName());
			if (!iBuildFile.exists()) {
				try {
					iBuildFile.createLink(new Path(buildFile.getAbsolutePath()), IResource.ALLOW_MISSING_LOCAL, monitor);
				}
				catch (CoreException e) {
					ErrorDialog.openError(getShell(), DataTransferMessages.AntNewJavaProjectPage_22, null, e.getStatus());
				}
			}
		} else {
			IImportStructureProvider structureProvider = FileSystemStructureProvider.INSTANCE;
			File rootDir = buildFile.getParentFile();
			try {
				ImportOperation op = new ImportOperation(javaProject.getPath(), rootDir, structureProvider, new ImportOverwriteQuery(), Collections.singletonList(buildFile));
				op.setCreateContainerStructure(false);
				op.run(monitor);
			}
			catch (InterruptedException e) {
				// should not happen
			}
			catch (InvocationTargetException e) {
				Throwable t = e.getTargetException();
				if (t instanceof CoreException) {
					ErrorDialog.openError(getShell(), DataTransferMessages.AntNewJavaProjectPage_22, null, ((CoreException) t).getStatus());
				}
			}
		}
	}

	private List<?> resolveJavacTasks(List<?> javacNodes) {
		List<Object> resolvedJavacTasks = new ArrayList<>(javacNodes.size());
		Iterator<?> nodes = javacNodes.iterator();
		while (nodes.hasNext()) {
			AntTaskNode taskNode = (AntTaskNode) nodes.next();
			Task javacTask = taskNode.getTask();
			if (javacTask instanceof UnknownElement) {
				if (((UnknownElement) javacTask).getRealThing() == null) {
					javacTask.maybeConfigure();
				}

				resolvedJavacTasks.add(((UnknownElement) javacTask).getRealThing());
			} else {
				resolvedJavacTasks.add(javacTask);
			}
		}
		return resolvedJavacTasks;
	}

	private void getJavacNodes(List<AntTaskNode> javacNodes, IAntElement parent) {
		if (!parent.hasChildren()) {
			return;
		}
		List<IAntElement> children = parent.getChildNodes();
		for (IAntElement node : children) {
			if (node instanceof AntTargetNode) {
				getJavacNodes(javacNodes, node);
			} else if (node instanceof AntTaskNode) {
				AntTaskNode task = (AntTaskNode) node;
				if ("javac".equals(task.getName())) { //$NON-NLS-1$
					javacNodes.add(task);
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
	 */
	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			fLocationPathField.setFocus();
		}
	}

	/**
	 * Creates the table which displays the available targets
	 * 
	 * @param parent
	 *            the parent composite
	 */
	private void createTargetsTable(Composite parent) {
		Font font = parent.getFont();
		Label label = new Label(parent, SWT.NONE);
		label.setFont(font);
		label.setText(DataTransferMessages.AntNewJavaProjectPage_3);
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = 3;
		label.setLayoutData(gd);

		Table table = new Table(parent, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);

		GridData data = new GridData(GridData.FILL_BOTH);
		int availableRows = availableRows(parent);
		data.heightHint = table.getItemHeight() * (availableRows / 20);
		data.widthHint = 250;
		data.horizontalSpan = 3;
		table.setLayoutData(data);
		table.setFont(font);

		fTableViewer = new TableViewer(table);
		fTableViewer.setLabelProvider(new JavacTableLabelProvider());
		fTableViewer.setContentProvider(new AntModelContentProvider());
		fTableViewer.getControl().setEnabled(false);
	}

	/**
	 * Return the number of rows available in the current display using the current font.
	 * 
	 * @param parent
	 *            The Composite whose Font will be queried.
	 * @return int The result of the display size divided by the font size.
	 */
	private int availableRows(Composite parent) {

		int fontHeight = (parent.getFont().getFontData())[0].getHeight();
		int displayHeight = parent.getDisplay().getClientArea().height;

		return displayHeight / fontHeight;
	}
}
