/*******************************************************************************
 * Copyright (c) 2019 GK Software SE, 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:
 *     Stephan Herrmann - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.wizards.buildpaths;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;

import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;

import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.ModuleDependenciesList.ModuleKind;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.ModuleDependenciesList.ModulesLabelProvider;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.ModuleDialog.ListContentProvider;

public class ModuleSelectionDialog extends TrayDialog {

	// widgets:
	private TableViewer fViewer;
	private Button fOkButton;
	private Runnable fFlipMessage; // may show a wait message first, use this to flip to the normal message
	
	boolean fInSetSelection= false; // to avoid re-entrance -> StackOverflow

	// input data:
	private IJavaProject fJavaProject;
	private IClasspathEntry fJREEntry;

	// internal storage and one client-provided function:
	private Set<String> fAllIncluded; 		// transitive closure over modules already shown
	private List<String> fAvailableModules;	// additional modules outside fAllIncluded 
	private Function<List<String>, Set<String>> fClosureComputation;
	private Map<String,IModuleDescription> fModulesByName= new HashMap<>();

	// result:
	private List<String> fSelectedModules;

	/**
	 * Let the user select among available modules that are not yet included (explicitly or implicitly).
	 * @param shell for showing the dialog
	 * @param javaProject the java project whose build path is being configured
	 * @param jreEntry a classpath entry representing the JRE system library
	 * @param shownModules set of modules already shown in the LHS list ({@link ModuleDependenciesList})
	 * @param closureComputation a function from module names to their full transitive closure over 'requires'. 
	 */
	protected ModuleSelectionDialog(Shell shell, IJavaProject javaProject, IClasspathEntry jreEntry, List<String> shownModules, Function<List<String>, Set<String>> closureComputation) {
		super(shell);
		fJavaProject= javaProject;
		fJREEntry= jreEntry;
		fAllIncluded= closureComputation.apply(shownModules);
		fClosureComputation= closureComputation;
		if (jreEntry != null) {  // searching only modules from this JRE entry (quick)
			List<String> result= new ArrayList<>();
			for (IPackageFragmentRoot root : fJavaProject.findUnfilteredPackageFragmentRoots(fJREEntry)) {
				checkAddModule(result, root.getModuleDescription());
			}
			result.sort(String::compareTo);
			fAvailableModules= result;
		} else {  // searching all modules in the workspace (slow)
			new Job("Searching modules in workspace") {
				@Override
				public IStatus run(IProgressMonitor monitor) {
					try {
						fAvailableModules= searchAvailableModules(monitor);
						if (getReturnCode() == Window.CANCEL) {
							return Status.CANCEL_STATUS;
						}
						shell.getDisplay().asyncExec(() -> {
							if (fFlipMessage != null) {
								fFlipMessage.run();
							}
							fViewer.setInput(fAvailableModules);
							fViewer.refresh();
						});
					} catch (CoreException e) {
						return e.getStatus();
					}
					return Status.OK_STATUS;
				}
			}.schedule();
		}
	}

	private List<String> searchAvailableModules(IProgressMonitor monitor) throws CoreException {
		List<String> result= new ArrayList<>();
		SearchPattern pattern= SearchPattern.createPattern("*", IJavaSearchConstants.MODULE, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH|SearchPattern.R_CASE_SENSITIVE); //$NON-NLS-1$
		SearchRequestor requestor= new SearchRequestor() {
			@Override
			public void acceptSearchMatch(SearchMatch match) throws CoreException {
				Object element= match.getElement();
				if (element instanceof IModuleDescription) {
					checkAddModule(result, (IModuleDescription) element);
				}
			}
		};
		SearchParticipant[] participants= new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() };
		new SearchEngine().search(pattern, participants, SearchEngine.createWorkspaceScope(), requestor, monitor);
		if (getReturnCode() == Window.CANCEL) { // TODO: should cancelPressed() actively abort the search?
			return Collections.emptyList();
		}
		result.sort(String::compareTo);
		return result;
	}

	void checkAddModule(List<String> result, IModuleDescription moduleDescription) {
		if (moduleDescription == null)
			return;
		if (!fAllIncluded.contains(moduleDescription.getElementName())) {
			result.add(moduleDescription.getElementName());
		}
		fModulesByName.put(moduleDescription.getElementName(), moduleDescription); // hold on to module description to be used for getResult()
	}

	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(NewWizardMessages.ModuleSelectionDialog_addSystemModules_title);
// TODO:
//		PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, IJavaHelpContextIds.MODULE_DIALOG);
	}
	
	@Override
	protected int getShellStyle() {
		return super.getShellStyle() | SWT.RESIZE;
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite composite= (Composite) super.createDialogArea(parent);
		Label message= new Label(composite, SWT.NONE);
		
		TableViewer tableViewer= new TableViewer(composite, SWT.MULTI | SWT.BORDER);
		tableViewer.setContentProvider(new ListContentProvider());
		tableViewer.setLabelProvider(new ModulesLabelProvider(s -> ModuleKind.System));
		tableViewer.addSelectionChangedListener(this::selectionChanged);

		PixelConverter converter= new PixelConverter(parent);
		GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true);
		gd.widthHint= converter.convertWidthInCharsToPixels(50);
		gd.heightHint= converter.convertHeightInCharsToPixels(20);
		tableViewer.getControl().setLayoutData(gd);

		if (fAvailableModules == null) {
			message.setText("Searching modules in workspace ...");
			fFlipMessage= () ->  {
				message.setText(NewWizardMessages.ModuleSelectionDialog_addSystemModules_message);
			};
		} else {
			tableViewer.setInput(fAvailableModules);
			message.setText(NewWizardMessages.ModuleSelectionDialog_addSystemModules_message);
		}
		fViewer= tableViewer;
		return composite;
	}

	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		fOkButton = createButton(parent, IDialogConstants.OK_ID,
				NewWizardMessages.ModuleSelectionDialog_add_button, true);
		createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
	}

	private void selectionChanged(SelectionChangedEvent e) {
		IStructuredSelection selection= e.getStructuredSelection();
		if (selection == null || selection.isEmpty()) {
			fOkButton.setEnabled(false);
			return;
		}
		List<String> selectedNames= selection.toList();
		Set<String> closure= fClosureComputation.apply(selectedNames);
		if (closure.size() > selectedNames.size()) {
			// select all members of the closure:
			if (!fInSetSelection) {
				fInSetSelection= true;
				fViewer.setSelection(new StructuredSelection(new ArrayList<>(closure)));
				fInSetSelection= false;
			}
		}
		fOkButton.setEnabled(true);
		fSelectedModules= new ArrayList<>(closure); // remember result
	}

	public List<IModuleDescription> getResult() {
		return fSelectedModules.stream()
				.filter(m -> !fAllIncluded.contains(m)) // skip modules that are already included
				.map(fModulesByName::get)
				.collect(Collectors.toList());
	}
}
