/*******************************************************************************
 * Copyright (c) 2009, 2018 Red Hat, Inc.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Elliott Baron <ebaron@redhat.com> - initial API and implementation
 *******************************************************************************/
package org.eclipse.linuxtools.internal.valgrind.launch;

import java.io.File;
import java.io.FileFilter;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

public class ValgrindExportWizardPage extends WizardPage {

    private IPath outputPath;
    private CheckboxTableViewer viewer;
    private Text destText;

    protected ValgrindExportWizardPage(String pageName, String title, ImageDescriptor titleImage) {
        super(pageName, title, titleImage);
    }


    @Override
    public void createControl(Composite parent) {
        Composite top = new Composite(parent, SWT.NONE);
        top.setLayout(new GridLayout());
        top.setLayoutData(new GridData(GridData.FILL_BOTH));

        IPath logPath = null;

        // Retrieve location of Valgrind logs from launch configuration
        ILaunchConfiguration config = getPlugin().getCurrentLaunchConfiguration();
        if (config != null && config.exists()) {
            String strpath;
            try {
                strpath = config.getAttribute(LaunchConfigurationConstants.ATTR_INTERNAL_OUTPUT_DIR, (String) null);
                if (strpath != null) {
                    logPath = Path.fromPortableString(strpath);
                }
            } catch (CoreException e) {
                setErrorMessage(e.getLocalizedMessage());
                e.printStackTrace();
            }
        }

        Label selectFilesLabel = new Label(top, SWT.NONE);
        selectFilesLabel.setText(Messages.getString("ValgrindExportWizardPage.Viewer_label")); //$NON-NLS-1$

        viewer = CheckboxTableViewer.newCheckList(top, SWT.BORDER);
        viewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
        viewer.setContentProvider(new ArrayContentProvider());
        viewer.setLabelProvider(new LabelProvider() {
            @Override
            public String getText(Object element) {
                return ((File) element).getName();
            }

            @Override
            public Image getImage(Object element) {
                return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
            }
        });

        Composite selectAllNoneTop = new Composite(top, SWT.NONE);
        selectAllNoneTop.setLayout(new GridLayout(2, true));
        selectAllNoneTop.setLayoutData(new GridData(SWT.TRAIL, SWT.DEFAULT, false, false));

        Button selectAllButton = new Button(selectAllNoneTop, SWT.NONE);
        selectAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        selectAllButton.setText(Messages.getString("ValgrindExportWizardPage.Select_all")); //$NON-NLS-1$
		selectAllButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> viewer.setAllChecked(true)));

        Button deselectAllButton = new Button(selectAllNoneTop, SWT.NONE);
        deselectAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        deselectAllButton.setText(Messages.getString("ValgrindExportWizardPage.Deselect_all")); //$NON-NLS-1$
		deselectAllButton
				.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> viewer.setAllChecked(false)));

        createDestinationGroup(top);

        if (logPath != null) {
            // List all output files in our output directory from the recent launch
            File logs[] = logPath.toFile().listFiles((FileFilter) pathname -> pathname.isFile());
            viewer.setInput(logs);
            viewer.setAllChecked(true);
        }

        // catch any errors so far
        setPageComplete(isValid());

        setControl(top);
    }

    public IPath getOutputPath() {
        return outputPath;
    }

    public File[] getSelectedFiles() {
        Object[] selected = viewer.getCheckedElements();
        File[] files = new File[selected.length];
        System.arraycopy(selected, 0, files, 0, selected.length);
        return files;
    }

    private void createDestinationGroup(Composite top) {
        Group destGroup = new Group(top, SWT.SHADOW_OUT);
        destGroup.setText(Messages.getString("ValgrindExportWizardPage.Destination_group")); //$NON-NLS-1$
        destGroup.setLayout(new GridLayout(2, false));
        destGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        destText = new Text(destGroup, SWT.BORDER);
        destText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        destText.addModifyListener(e -> setPageComplete(isValid()));

        Button browseButton = new Button(destGroup, SWT.PUSH);
        browseButton.setText(Messages.getString("ValgrindExportWizardPage.Browse")); //$NON-NLS-1$
		browseButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
			// Prompt for output directory
			Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
			DirectoryDialog dialog = new DirectoryDialog(parent);
			dialog.setText(Messages.getString("ValgrindLaunchConfigurationDelegate.Select_Destination")); //$NON-NLS-1$
			String strpath = dialog.open();
			if (strpath != null) {
				destText.setText(strpath);
			}
		}));
    }

    private boolean isValid() {
        boolean valid = false;
        int length = -1;

        setErrorMessage(null);
        setMessage(null);

        Object obj = viewer.getInput();
        // Check if there are no launch files (either null because directory is missing
        // or 0 files are found in directory)
        if (obj instanceof File[])
            length = ((File[])obj).length;
        if (viewer.getInput() == null || length == 0) {
            setErrorMessage(Messages.getString("ValgrindExportWizardPage.Err_No_Valgrind_run")); //$NON-NLS-1$
        }
        else if (destText.getText().equals("")) { //$NON-NLS-1$
            setMessage(Messages.getString("ValgrindExportWizardPage.Msg_Select_destination")); //$NON-NLS-1$
        }
        else {
            IPath path = Path.fromOSString(destText.getText());
            if (!path.toFile().exists()) {
                setErrorMessage(NLS.bind(Messages.getString("ValgrindExportWizardPage.Err_Dir_not_exist"), path.toOSString())); //$NON-NLS-1$
            }
            else if (!path.toFile().isDirectory()) {
                setErrorMessage(NLS.bind(Messages.getString("ValgrindExportWizardPage.Err_Not_dir"), path.toOSString())); //$NON-NLS-1$
            }
            else {
                outputPath = path;
                valid = true;
            }
        }

        return valid;
    }

    private ValgrindLaunchPlugin getPlugin() {
        return ValgrindLaunchPlugin.getDefault();
    }

    public CheckboxTableViewer getViewer() {
        return viewer;
    }

    public Text getDestText() {
        return destText;
    }
}
