/*******************************************************************************
 * Copyright (c) 2015 Red Hat Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Mickael Istria (Red Hat Inc.) - initial API and implementation
 ******************************************************************************/
package org.eclipse.ui.internal.wizards.datatransfer;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IPageChangeProvider;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.wizards.datatransfer.ProjectConfigurator;

public class ImportProposalsWizardPage extends WizardPage implements IPageChangedListener {

	private CheckboxTreeViewer tree;
	private Set<File> alreadyExistingProjects;
	private Set<File> notAlreadyExistingProjects;
	private Button recurseInSelectedProjectsCheckbox;
	private EasymportJob currentJob;
	private Label selectionSummary;

	private class FolderForProjectsLabelProvider extends LabelProvider implements IColorProvider {
		@Override
		public String getText(Object o) {
			if (alreadyExistingProjects.contains(o)) {
				return super.getText(o)+ " (" + Messages.alreadyImportedAsProject_title + ")"; //$NON-NLS-1$ //$NON-NLS-2$
			}
			return super.getText(o);
		}

		@Override
		public Color getBackground(Object o) {
			return null;
		}

		@Override
		public Color getForeground(Object o) {
			if (alreadyExistingProjects.contains(o)) {
				return Display.getDefault().getSystemColor(SWT.COLOR_GRAY);
			}
			return null;
		}
	}
	
	public ImportProposalsWizardPage(EasymportWizard wizard) {
		super(ImportProposalsWizardPage.class.getName());
		setWizard(wizard);
	}

	@Override
	public void createControl(Composite parent) {
		setTitle(Messages.preliminaryDetection_Title);
		setDescription(Messages.preliminaryDetection_Description);

		if (getContainer() instanceof IPageChangeProvider) {
			((IPageChangeProvider)getContainer()).addPageChangedListener(this);
		}

		Composite res = new Composite(parent, SWT.NONE);
		res.setLayout(new GridLayout(2, false));
		selectionSummary = new Label(res, SWT.NONE);
		selectionSummary.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 2, 1));
		tree = new CheckboxTreeViewer(res, SWT.BORDER);
		tree.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		tree.setContentProvider(new ITreeContentProvider() {
			@Override
			public void dispose() {
			}

			@Override
			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			}

			@Override
			public Object[] getElements(Object inputElement) {
				Map<File, ?> potentialProjects = (Map<File, ?>)inputElement;
				return potentialProjects.keySet().toArray(new File[potentialProjects.size()]);
			}
			

			@Override
			public Object[] getChildren(Object parentElement) {
				return null;
			}

			@Override
			public Object getParent(Object element) {
				return null;
			}

			@Override
			public boolean hasChildren(Object element) {
				return false;
			}
			
		});
		tree.setLabelProvider(new LabelProvider() {
			@Override
			public String getText(Object o) {
				return ((File)o).getAbsolutePath();
			}
		});
		tree.setComparator(new ViewerComparator() {
			@Override
			public int compare(Viewer v, Object o1, Object o2) {
				return ((File)o1).getAbsolutePath().compareTo(((File)o2).getAbsolutePath());
			}
		});
		tree.addCheckStateListener(new ICheckStateListener() {
			@Override
			public void checkStateChanged(CheckStateChangedEvent event) {
				if (ImportProposalsWizardPage.this.alreadyExistingProjects.contains(event.getElement())) {
					tree.setChecked(event.getElement(), false);
				} else {
					selectionChanged();
				}
			}
		});
		tree.setLabelProvider(new FolderForProjectsLabelProvider());
		
		Composite selectionButtonsGroup = new Composite(res, SWT.NONE);
		selectionButtonsGroup.setLayout(new GridLayout(1, false));
		selectionButtonsGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
		Button selectAllButton = new Button(selectionButtonsGroup, SWT.PUSH);
		selectAllButton.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, false, false));
		selectAllButton.setText(DataTransferMessages.DataTransfer_selectAll);
		selectAllButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				tree.setCheckedElements(ImportProposalsWizardPage.this.notAlreadyExistingProjects.toArray());
				selectionChanged();
			}
		});
		Button deselectAllButton = new Button(selectionButtonsGroup, SWT.PUSH);
		deselectAllButton.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, false, false));
		deselectAllButton.setText(DataTransferMessages.DataTransfer_deselectAll);
		deselectAllButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				tree.setCheckedElements(new Object[0]);
				selectionChanged();
			}
		});
		
		recurseInSelectedProjectsCheckbox = new Button(res, SWT.CHECK);
		recurseInSelectedProjectsCheckbox.setText("Use additional analysis after import to detect nested project under selected projects\n(BEWARE: this may create new projects in your workspace without ability to review it first!)");
		recurseInSelectedProjectsCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, false, false, 2, 1));
		recurseInSelectedProjectsCheckbox.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				getWizard().getImportJob().setDetectNestedProjects(recurseInSelectedProjectsCheckbox.getSelection());
			}
		});
		setPageComplete(true);
		setControl(res);
	}

	@Override
	public boolean isPageComplete() {
		return getWizard().getImportJob() != null &&
			getWizard().getImportJob().getDirectoriesToImport() != null &&
			!getWizard().getImportJob().getDirectoriesToImport().isEmpty();
	}


	@Override
	public void setWizard(IWizard easymportWizard) {
		Assert.isTrue(easymportWizard instanceof EasymportWizard);
		super.setWizard(easymportWizard);
	}
	
	public EasymportWizard getWizard() {
		return (EasymportWizard)super.getWizard();
	}

	private void updateTreeContent() {
		try {
			getContainer().run(false, false, new IRunnableWithProgress() {
				@Override
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					final Map<File, List<ProjectConfigurator>> potentialProjects = getWizard().getImportJob().getImportProposals(monitor);
					if (potentialProjects.size() == 0) {
						MessageDialog.openInformation(getShell(),
								Messages.didntFindImportProposals_title,
								NLS.bind(Messages.didntFindImportProposals_message, recurseInSelectedProjectsCheckbox.getText()));
					} else {
						// if some projects were detected thanks to metadata, assume projects has necessary metadata for good import
						// and skip additional nested project detection.
						getWizard().getImportJob().setDetectNestedProjects(false);
					}
					recurseInSelectedProjectsCheckbox.setSelection(getWizard().getImportJob().isDetectNestedProjects());
					if (!potentialProjects.containsKey(getWizard().getImportJob().getRoot())) {
						potentialProjects.put(getWizard().getImportJob().getRoot(), Collections.EMPTY_LIST);
						// force nested detection when the import didn't manage to do something 
						getWizard().getImportJob().setDetectNestedProjects(true);
					}
					
					ImportProposalsWizardPage.this.notAlreadyExistingProjects = new HashSet<File>(potentialProjects.keySet());
					ImportProposalsWizardPage.this.alreadyExistingProjects = new HashSet<File>();
					for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
						ImportProposalsWizardPage.this.notAlreadyExistingProjects.remove(project.getLocation().toFile());
						ImportProposalsWizardPage.this.alreadyExistingProjects.add(project.getLocation().toFile());
					}
					tree.setInput(potentialProjects);
					tree.setCheckedElements(ImportProposalsWizardPage.this.notAlreadyExistingProjects.toArray());
				}
			});
			selectionChanged();
		} catch (InterruptedException ex) {
			tree.setInput(Collections.EMPTY_MAP);
			getWizard().getImportJob().resetProposals();
		} catch (InvocationTargetException ex) {
			MessageDialog.openError(getShell(), "Sorry...", "An internal error occured. Please see log file for details.");
			Activator.getDefault().getLog().log(new Status(IStatus.ERROR,
					Activator.getDefault().getBundle().getSymbolicName(),
					ex.getMessage(),
					ex));
		}
	}

	@Override
	public void pageChanged(PageChangedEvent event) {
		if (event.getSelectedPage() == this) {
			EasymportJob newJob = getWizard().getImportJob();
			if (newJob != this.currentJob) {
				this.currentJob = newJob;
				recurseInSelectedProjectsCheckbox.setSelection(getWizard().getImportJob().isDetectNestedProjects());
				updateTreeContent();
			}
		}
	}
	
	@Override
	public void dispose() {
		if (getContainer() instanceof IPageChangeProvider) {
			((IPageChangeProvider)getContainer()).removePageChangedListener(this);
		}
		super.dispose();
	}

	private void selectionChanged() {
		Object[] selected = tree.getCheckedElements();
		EasymportJob importJob = getWizard().getImportJob();
		Set<File> excludedDirectories = new HashSet(((Map<File, ?>)this.tree.getInput()).keySet());
		Set<File> selectedProjects = new HashSet<File>();
		for (Object item : selected) {
			File directory = (File)item;
			excludedDirectories.remove(directory);
			selectedProjects.add(directory);
		}
		importJob.setDirectoriesToImport(selectedProjects);
		importJob.setExcludedDirectories(excludedDirectories);
		selectionSummary.setText(NLS.bind(Messages.selectionSummary, importJob.getImportProposals(null).size(), importJob.getDirectoriesToImport().size()));
		setPageComplete(isPageComplete());
	}
}
