/*******************************************************************************
 * 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.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.CheckboxTableViewer;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
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(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 = 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);
	}

	@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 = pm -> {
			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 e1) {
				problem = e1;
			}
			catch (TransformerConfigurationException e2) {
				problem = e2;
			}
			catch (ParserConfigurationException e3) {
				problem = e3;
			}
			catch (TransformerException e4) {
				problem = e4;
			}
			catch (IOException e5) {
				problem = e5;
			}
			catch (CoreException e6) {
				problem = e6;
			}

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