/*******************************************************************************
 * Copyright (c) 2004, 2013 Richard Hoefter 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:
 *     Richard Hoefter (richard.hoefter@web.de) - initial API and implementation, bug 95296, bug 288830
 *     IBM Corporation - adapted to wizard export page
 *******************************************************************************/

package org.eclipse.ant.internal.ui.datatransfer;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.wizard.WizardPage;
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.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.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;

import com.ibm.icu.text.MessageFormat;

public class AntBuildfileExportPage extends WizardPage {

	private CheckboxTableViewer fTableViewer;
	private List<IJavaProject> fSelectedJavaProjects = new ArrayList<>();
	private Button compatibilityCheckbox;
	private Button compilerCheckbox;
	private Text buildfilenameText;
	private Text junitdirText;

	public AntBuildfileExportPage() {
		super("AntBuildfileExportWizardPage"); //$NON-NLS-1$
		setPageComplete(false);
		setTitle(DataTransferMessages.AntBuildfileExportPage_0);
		setDescription(DataTransferMessages.AntBuildfileExportPage_1);
	}

	/*
	 * @see IDialogPage#createControl(Composite)
	 */
	@Override
	public void createControl(Composite parent) {

		initializeDialogUnits(parent);

		Composite workArea = new Composite(parent, SWT.NONE);
		setControl(workArea);

		workArea.setLayout(new GridLayout());
		workArea.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));

		Label titel = new Label(workArea, SWT.NONE);
		titel.setText(DataTransferMessages.AntBuildfileExportPage_2);

		Composite listComposite = new Composite(workArea, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginWidth = 0;
		layout.makeColumnsEqualWidth = false;
		listComposite.setLayout(layout);

		listComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH));

		// TODO set F1 help

		Table table = new Table(listComposite, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
		fTableViewer = new CheckboxTableViewer(table);
		table.setLayout(new TableLayout());
		GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
		data.heightHint = 300;
		table.setLayoutData(data);
		fTableViewer.setContentProvider(new WorkbenchContentProvider() {
			@Override
			public Object[] getElements(Object element) {
				if (element instanceof IJavaProject[]) {
					return (IJavaProject[]) element;
				}
				return null;
			}
		});
		fTableViewer.setLabelProvider(new WorkbenchLabelProvider());
		fTableViewer.addCheckStateListener(new ICheckStateListener() {
			@Override
			public void checkStateChanged(CheckStateChangedEvent event) {
				if (event.getChecked()) {
					fSelectedJavaProjects.add((IJavaProject) event.getElement());
				} else {
					fSelectedJavaProjects.remove(event.getElement());
				}
				updateEnablement();
			}
		});

		initializeProjects();
		createSelectionButtons(listComposite);
		createCheckboxes(workArea);
		createTextFields(workArea);
		setControl(workArea);
		updateEnablement();
		Dialog.applyDialogFont(parent);
	}

	private void createSelectionButtons(Composite composite) {

		Composite buttonsComposite = new Composite(composite, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		buttonsComposite.setLayout(layout);

		buttonsComposite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));

		Button selectAll = new Button(buttonsComposite, SWT.PUSH);
		selectAll.setText(DataTransferMessages.AntBuildfileExportPage_11);
		selectAll.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				for (int i = 0; i < fTableViewer.getTable().getItemCount(); i++) {
					fSelectedJavaProjects.add((IJavaProject) fTableViewer.getElementAt(i));
				}
				fTableViewer.setAllChecked(true);
				updateEnablement();
			}
		});
		setButtonLayoutData(selectAll);

		Button deselectAll = new Button(buttonsComposite, SWT.PUSH);
		deselectAll.setText(DataTransferMessages.AntBuildfileExportPage_12);
		deselectAll.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				fSelectedJavaProjects.clear();
				fTableViewer.setAllChecked(false);
				updateEnablement();
			}
		});
		setButtonLayoutData(deselectAll);
	}

	private void createCheckboxes(Composite composite) {

		compatibilityCheckbox = new Button(composite, SWT.CHECK);
		compatibilityCheckbox.setSelection(true);
		compatibilityCheckbox.setText(DataTransferMessages.AntBuildfileExportPage_13);
		compatibilityCheckbox.setToolTipText(DataTransferMessages.AntBuildfileExportPage_14);

		compilerCheckbox = new Button(composite, SWT.CHECK);
		compilerCheckbox.setSelection(true);
		compilerCheckbox.setText(DataTransferMessages.AntBuildfileExportPage_15);
	}

	private void createTextFields(Composite composite) {

		// buildfilename and junitdir group
		Composite containerGroup = new Composite(composite, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		containerGroup.setLayout(layout);
		containerGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));

		// label
		Label buildfilenameLabel = new Label(containerGroup, SWT.NONE);
		buildfilenameLabel.setText(DataTransferMessages.AntBuildfileExportPage_16);

		// text field
		buildfilenameText = new Text(containerGroup, SWT.SINGLE | SWT.BORDER);
		buildfilenameText.setText("build.xml"); //$NON-NLS-1$
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
		buildfilenameText.setLayoutData(data);

		// label
		Label junitdirLabel = new Label(containerGroup, SWT.NONE);
		junitdirLabel.setText(DataTransferMessages.AntBuildfileExportPage_17);

		// text field
		junitdirText = new Text(containerGroup, SWT.SINGLE | SWT.BORDER);
		junitdirText.setText("junit"); //$NON-NLS-1$
		junitdirText.setLayoutData(data);

		ModifyListener listener = new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent e) {
				updateEnablement();
			}
		};
		buildfilenameText.addModifyListener(listener);
		junitdirText.addModifyListener(listener);
	}

	private void initializeProjects() {
		IWorkspaceRoot rootWorkspace = ResourcesPlugin.getWorkspace().getRoot();
		IJavaModel javaModel = JavaCore.create(rootWorkspace);
		IJavaProject[] javaProjects;
		try {
			javaProjects = javaModel.getJavaProjects();
		}
		catch (JavaModelException e) {
			javaProjects = new IJavaProject[0];
		}
		fTableViewer.setInput(javaProjects);
		// Check any necessary projects
		if (fSelectedJavaProjects != null) {
			fTableViewer.setCheckedElements(fSelectedJavaProjects.toArray(new IJavaProject[fSelectedJavaProjects.size()]));
		}
	}

	private void updateEnablement() {
		boolean complete = true;
		if (fSelectedJavaProjects.isEmpty()) {
			setErrorMessage(DataTransferMessages.AntBuildfileExportPage_18);
			complete = false;
		}
		try {
			List<String> projectsWithErrors = new ArrayList<>();
			List<String> projectsWithWarnings = new ArrayList<>();
			findCyclicProjects(getProjects(false), projectsWithErrors, projectsWithWarnings);
			if (projectsWithErrors.size() > 0) {
				String message = DataTransferMessages.AntBuildfileExportPage_cycle_error_in_projects;
				if (projectsWithErrors.size() == 1) {
					message = DataTransferMessages.AntBuildfileExportPage_cycle_error_in_project;
				}
				setErrorMessage(MessageFormat.format(message, new Object[] { ExportUtil.toString(projectsWithErrors, ", ") })); //$NON-NLS-1$
				complete = false;
			} else if (projectsWithWarnings.size() > 0) {
				String message = DataTransferMessages.AntBuildfileExportPage_cycle_warning_in_projects;
				if (projectsWithWarnings.size() == 1) {
					message = DataTransferMessages.AntBuildfileExportPage_cycle_warning_in_project;
				}
				setMessage(MessageFormat.format(message, new Object[] { ExportUtil.toString(projectsWithWarnings, ", ") }), WARNING); //$NON-NLS-1$
			} else {
				setMessage(null);
			}
		}
		catch (CoreException e) {
			// do nothing
		}
		if (buildfilenameText.getText().length() == 0) {
			setErrorMessage(DataTransferMessages.AntBuildfileExportPage_19);
			complete = false;
		}
		if (junitdirText.getText().length() == 0) {
			setErrorMessage(DataTransferMessages.AntBuildfileExportPage_20);
			complete = false;
		}
		if (complete) {
			setErrorMessage(null);
		}
		setPageComplete(complete);
	}

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

	protected void setSelectedProjects(List<IJavaProject> selectedJavaProjects) {
		fSelectedJavaProjects.addAll(selectedJavaProjects);
	}

	/**
	 * Convert Eclipse Java projects to Ant build files. Displays error dialogs.
	 */
	public boolean generateBuildfiles() {
		setErrorMessage(null);
		final List<String> projectNames = new ArrayList<>();
		final Set<IJavaProject> projects;
		try {
			projects = getProjects(true);
			if (projects.isEmpty()) {
				return false;
			}
		}
		catch (JavaModelException e) {
			AntUIPlugin.log(e);
			setErrorMessage(MessageFormat.format(DataTransferMessages.AntBuildfileExportPage_10, new Object[] { e.toString() }));
			return false;
		}
		IRunnableWithProgress runnable = new IRunnableWithProgress() {
			@Override
			public void run(IProgressMonitor pm) throws InterruptedException {
				SubMonitor localmonitor = SubMonitor.convert(pm, DataTransferMessages.AntBuildfileExportPage_creating_build_files, projects.size());
				Exception problem = null;
				try {
					BuildFileCreator.setOptions(buildfilenameText.getText(), junitdirText.getText(), compatibilityCheckbox.getSelection(), compilerCheckbox.getSelection());
					projectNames.addAll(BuildFileCreator.createBuildFiles(projects, getShell(), localmonitor.newChild(projects.size())));
				}
				catch (JavaModelException e) {
					problem = e;
				}
				catch (TransformerConfigurationException e) {
					problem = e;
				}
				catch (ParserConfigurationException e) {
					problem = e;
				}
				catch (TransformerException e) {
					problem = e;
				}
				catch (IOException e) {
					problem = e;
				}
				catch (CoreException e) {
					problem = e;
				}

				if (problem != null) {
					AntUIPlugin.log(problem);
					setErrorMessage(MessageFormat.format(DataTransferMessages.AntBuildfileExportPage_10, new Object[] { problem.toString() }));
				}
			}
		};

		try {
			getContainer().run(false, false, runnable);
		}
		catch (InvocationTargetException e) {
			AntUIPlugin.log(e);
			return false;
		}
		catch (InterruptedException e) {
			AntUIPlugin.log(e);
			return false;
		}
		if (getErrorMessage() != null) {
			return false;
		}
		return true;
	}

	/**
	 * Get projects to write buildfiles for. Opens confirmation dialog.
	 * 
	 * @param displayConfirmation
	 *            if set to true a dialog prompts for confirmation before overwriting files
	 * @return set of project names
	 */
	private Set<IJavaProject> getProjects(boolean displayConfirmation) throws JavaModelException {
		// collect all projects to create buildfiles for
		Set<IJavaProject> projects = new TreeSet<>(ExportUtil.getJavaProjectComparator());
		Iterator<IJavaProject> javaProjects = fSelectedJavaProjects.iterator();
		while (javaProjects.hasNext()) {
			IJavaProject javaProject = javaProjects.next();
			projects.addAll(ExportUtil.getClasspathProjectsRecursive(javaProject));
			projects.add(javaProject);
		}

		// confirm overwrite
		List<String> confirmOverwrite = getConfirmOverwriteSet(projects);
		if (displayConfirmation && confirmOverwrite.size() > 0) {
			String message = DataTransferMessages.AntBuildfileExportPage_3 + ExportUtil.NEWLINE
					+ ExportUtil.toString(confirmOverwrite, ExportUtil.NEWLINE);
			if (!MessageDialog.openQuestion(getShell(), DataTransferMessages.AntBuildfileExportPage_4, message)) {
				return new TreeSet<>(ExportUtil.getJavaProjectComparator());
			}
		}
		return projects;
	}

	/**
	 * Splits a set of given projects into a list of projects that have cyclic dependency errors and a list of projects that have cyclic dependency
	 * warnings.
	 */
	private void findCyclicProjects(Set<IJavaProject> projects, List<String> errors, List<String> warnings) throws CoreException {
		for (IJavaProject javaProject : projects) {
			IMarker marker = ExportUtil.getCyclicDependencyMarker(javaProject);
			if (marker != null) {
				Integer severityAttr = (Integer) marker.getAttribute(IMarker.SEVERITY);
				if (severityAttr != null) {
					switch (severityAttr.intValue()) {
						case IMarker.SEVERITY_ERROR:
							errors.add(javaProject.getProject().getName());
							break;
						case IMarker.SEVERITY_WARNING:
							warnings.add(javaProject.getProject().getName());
							break;
						default:
							break;
					}
				}
			}
		}
	}

	/**
	 * Get list of projects which have already a buildfile that was not created by the buildfile export.
	 * 
	 * @param javaProjects
	 *            list of IJavaProject objects
	 * @return set of project names
	 */
	private List<String> getConfirmOverwriteSet(Set<IJavaProject> javaProjects) {
		List<String> result = new ArrayList<>(javaProjects.size());
		for (IJavaProject project : javaProjects) {
			String projectRoot = ExportUtil.getProjectRoot(project);
			if (ExportUtil.existsUserFile(projectRoot + buildfilenameText.getText())) {
				result.add(project.getProject().getName());
			}
		}
		return result;
	}
}