/*******************************************************************************
 * Copyright (c) 2007-2019 Cisco Systems, 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:
 *    E. Dillon (Cisco Systems, Inc.) - reformat for Code Open-Sourcing
 *******************************************************************************/
package org.eclipse.tigerstripe.workbench.ui.internal.dialogs;

import static java.util.Arrays.asList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
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.Shell;
import org.eclipse.tigerstripe.workbench.TigerstripeException;
import org.eclipse.tigerstripe.workbench.internal.BasePlugin;
import org.eclipse.tigerstripe.workbench.internal.core.module.InstalledModule;
import org.eclipse.tigerstripe.workbench.internal.core.module.InstalledModuleManager;
import org.eclipse.tigerstripe.workbench.project.IDependency;
import org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProject;
import org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProjectInternal;
import org.eclipse.tigerstripe.workbench.ui.EclipsePlugin;
import org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.dependencies.DependenciesImageProvider;
import org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.dependencies.DependenciesSorter;
import org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.dependencies.DependencyKind;
import org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.dependencies.IDependencyKindResolver;
import org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.dependencies.ITextProvider;
import org.eclipse.ui.dialogs.SelectionStatusDialog;

/**
 * Presents the user with a filterable list of Tigerstripe projects for
 * selection
 * 
 * @author Eric Dillon
 * 
 */
public class TigerstripeProjectSelectionDialog extends SelectionStatusDialog implements IProjectSelectionDialog {
    // sizing constants
    private static final int SIZING_SELECTION_WIDGET_HEIGHT = 250;

    private static final int SIZING_SELECTION_WIDGET_WIDTH = 300;

    private static final Set<String> DEPENDENCIES_EXTENSIONS = new HashSet<>(asList("jar", "zip"));

    // the visual selection widget group
    private TableViewer fTableViewer;

    private Set<String> fFilteredOutProjects;

    private ViewerFilter fFilter;

    private final ITigerstripeModelProject currentProject;

    private static final IDependencyKindResolver KIND_RESOLVER = obj -> {
        if (obj instanceof IJavaProject) {
            return DependencyKind.PROJECT;
        } else if (obj instanceof InstalledModule) {
            return DependencyKind.MODULE;
        } else if (obj instanceof IResource) {
            return DependencyKind.DEPENDENCY;
        } else {
            return DependencyKind.UNKNOWN;
        }
    };

    class TigerstripeProjectReferencesProvider extends StandardJavaElementContentProvider {
        @Override
        public Object[] getElements(Object parent) {
            Map<String, Object> projsAndModulesMap = new HashMap<>();
            Object[] javaResult = super.getElements(parent);
            InstalledModule[] modules = InstalledModuleManager.getInstance().getModules();

            Collection<Object> projsAndModules = new ArrayList<>();
            projsAndModules.addAll(asList(javaResult));
            projsAndModules.addAll(asList(modules));

            for (Object o : projsAndModules) {
                String id;
                if (o instanceof IJavaProject) {
                    IJavaProject javaProject = (IJavaProject) o;
                    ITigerstripeModelProject tsp = javaProject.getAdapter(ITigerstripeModelProject.class);
                    if (tsp != null) {
                        try {
                            id = tsp.getModelId();
                        } catch (TigerstripeException e) {
                            BasePlugin.log(e);
                            continue;
                        }
                    } else {
                        continue;
                    }
                } else if (o instanceof InstalledModule) {
                    InstalledModule module = (InstalledModule) o;
                    id = module.getModuleID();
                } else {
                    continue;
                }

                if (!projsAndModulesMap.containsKey(id)) {
                    projsAndModulesMap.put(id, o);
                }
            }
            Collection<IResource> dependencies = findDependencies();
            Set<Object> all = new HashSet<>(projsAndModulesMap.size() + dependencies.size());
            all.addAll(projsAndModulesMap.values());
            all.addAll(dependencies);
            return all.toArray(new Object[0]);
        }
    }

    private Collection<IResource> findDependencies() {

        IProject project = ((ITigerstripeModelProjectInternal) currentProject).getAdapter(IProject.class);

        // Need to be careful that we don;t pick up anything that is in the
        // target directory as a potential dependency.
        IContainer targetFolder = null;

        try {
            IPath output = new Path(currentProject.getProjectDetails().getOutputDirectory());
            if (output.segmentCount() > 1) {
                output = output.removeLastSegments(output.segmentCount() - 1);
            }
            IResource res = project.findMember(output);
            if (res instanceof IContainer) {
                targetFolder = (IContainer) res;
            }
        } catch (TigerstripeException e1) {
            // ignore
        }

        final Collection<IResource> result = new HashSet<>();
        final IContainer targetContainer = targetFolder;

        try {
            project.accept(new IResourceVisitor() {
                public boolean visit(IResource resource) throws CoreException {
                    if (resource.getParent().equals(targetContainer)) {
                        return false;
                    }

                    if (resource instanceof IFile) {
                        if (DEPENDENCIES_EXTENSIONS.contains(resource.getFileExtension())) {
                            result.add(resource);
                        }
                        return false;
                    }
                    return true;
                }
            });
        } catch (CoreException e) {
            EclipsePlugin.log(e);
        }
        return result;
    }

    static class TigerstripeProjectReferencesLabelProvider extends JavaElementLabelProvider {

        private final DependenciesImageProvider imageProvider = new DependenciesImageProvider(KIND_RESOLVER);

        public TigerstripeProjectReferencesLabelProvider() {
            super(SHOW_PARAMETERS | SHOW_SMALL_ICONS);
        }

        @Override
        public String getText(Object element) {
            if (element instanceof InstalledModule) {
                InstalledModule module = (InstalledModule) element;
                StringBuilder buffer = new StringBuilder();
                buffer.append(module.getModuleID());
                String version = module.getModule().getProjectDetails().getVersion();
                if (version != null && version.length() > 0) {
                    buffer.append(" (");
                    buffer.append(version);
                    buffer.append(")");
                }
                return buffer.toString();
            } else if (element instanceof IResource) {
                return ((IResource) element).getName();
            } else {
                return super.getText(element);
            }
        }

        @Override
        public Image getImage(Object element) {
            return imageProvider.getImage(element);
        }
    }

    public TigerstripeProjectSelectionDialog(Shell parentShell, Set<String> filteredOutProjects,
            final ITigerstripeModelProjectInternal currentProject) {
        super(parentShell);
        this.currentProject = currentProject;
        setTitle("Select Tigerstripe Project");
        setMessage("Select Tigerstripe Project to reference");
        fFilteredOutProjects = filteredOutProjects;

        int shellStyle = getShellStyle();
        setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);

        fFilter = new ViewerFilter() {
            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {
                if (element instanceof IJavaProject) {
                    IJavaProject prj = (IJavaProject) element;
                    ITigerstripeModelProject tsProject = prj.getProject().getAdapter(ITigerstripeModelProject.class);
                    if (tsProject != null && tsProject.exists()) {
                        try {
                            return fFilteredOutProjects.contains(tsProject.getModelId());
                        } catch (TigerstripeException e) {
                            // Ignore
                        }
                    }
                    return false;
                } else if (element instanceof InstalledModule) {
                    return fFilteredOutProjects.contains(((InstalledModule) element).getModuleID());
                } else if (element instanceof IResource) {
                    try {
                        IDependency[] dependencies = currentProject.getDependencies();
                        for (IDependency dep : dependencies) {
                            if (dep.getPath().equals(((IResource) element).getProjectRelativePath().toOSString())) {
                                return false;
                            }
                        }
                        return true;
                    } catch (TigerstripeException e) {
                        EclipsePlugin.log(e);
                        return false;
                    }
                } else {
                    return false;
                }
            }
        };

    }

    /*
     * (non-Javadoc) Method declared on Dialog.
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        // page group
        Composite composite = (Composite) super.createDialogArea(parent);

        Font font = parent.getFont();
        composite.setFont(font);

        createMessageArea(composite);

        fTableViewer = new TableViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI);
        fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                doSelectionChanged(((IStructuredSelection) event.getSelection()).toArray());
            }
        });
        fTableViewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                okPressed();
            }
        });
        fTableViewer.addFilter(fFilter);

        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
        data.heightHint = SIZING_SELECTION_WIDGET_HEIGHT;
        data.widthHint = SIZING_SELECTION_WIDGET_WIDTH;
        fTableViewer.getTable().setLayoutData(data);

        final TigerstripeProjectReferencesLabelProvider labelProvider = new TigerstripeProjectReferencesLabelProvider();

        fTableViewer.setLabelProvider(labelProvider);
        fTableViewer.setContentProvider(new TigerstripeProjectReferencesProvider());

        ITextProvider textAdapter = new ITextProvider() {

            public String getText(Object obj) {
                return labelProvider.getText(obj);
            }
        };

        fTableViewer.setComparator(new DependenciesSorter(textAdapter, KIND_RESOLVER));
        fTableViewer.getControl().setFont(font);

        final Button checkbox = new Button(composite, SWT.CHECK);
        checkbox.setText("Add Transitive dependencies");
        checkbox.setSelection(isIncludeTransitiveDependencies());
        checkbox.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false));

        checkbox.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                setIncludeTransitiveDependencies(checkbox.getSelection());
            }

        });
        
        IJavaModel input = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
        fTableViewer.setInput(input);

        doSelectionChanged(new Object[0]);
        Dialog.applyDialogFont(composite);
        return composite;
    }

    private boolean includeTransitive = false;

    public boolean isIncludeTransitiveDependencies() {
        return includeTransitive;
    }

    private void setIncludeTransitiveDependencies(boolean b) {
        includeTransitive = b;
    }

    private void doSelectionChanged(Object[] objects) {
        if (objects.length == 0) {
            updateStatus(new StatusInfo(IStatus.ERROR, "")); //$NON-NLS-1$
            setSelectionResult(null);
        } else {
            updateStatus(new StatusInfo());
            setSelectionResult(objects);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.dialogs.SelectionStatusDialog#computeResult()
     */
    @Override
    protected void computeResult() {
    }

}
