/*******************************************************************************
 *  Copyright (c) 2008, 2017 IBM Corporation 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:
 *      IBM Corporation - initial API and implementation
 *      Fabian Steeg <steeg@hbz-nrw.de> - Bug 474099 - Require certificate selection to confirm dialog
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.dialogs;

import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;

import java.io.*;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
import org.eclipse.equinox.internal.p2.ui.viewers.CertificateLabelProvider;
import org.eclipse.equinox.internal.provisional.security.ui.X509CertificateViewDialog;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.dialogs.SelectionDialog;

/**
 * A dialog that displays a certificate chain and asks the user if they trust
 * the certificate providers.
 */
public class TrustCertificateDialog extends SelectionDialog {

	private Object inputElement;
	private IStructuredContentProvider contentProvider;
	private ILabelProvider labelProvider;

	private final static int SIZING_SELECTION_WIDGET_HEIGHT = 250;
	private final static int SIZING_SELECTION_WIDGET_WIDTH = 300;

	CheckboxTableViewer listViewer;

	private TreeViewer certificateChainViewer;
	private Button detailsButton;
	protected TreeNode parentElement;
	protected Object selectedCertificate;

	public TrustCertificateDialog(Shell parentShell, Object input, ILabelProvider labelProvider,
			ITreeContentProvider contentProvider) {
		super(parentShell);
		inputElement = input;
		this.contentProvider = contentProvider;
		this.labelProvider = labelProvider;
		setTitle(ProvUIMessages.TrustCertificateDialog_Title);
		setMessage(ProvUIMessages.TrustCertificateDialog_Message);
		setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS | SWT.RESIZE | getDefaultOrientation());
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite composite = createUpperDialogArea(parent);
		certificateChainViewer = new TreeViewer(composite, SWT.BORDER);
		GridLayout layout = new GridLayout();
		certificateChainViewer.getTree().setLayout(layout);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.grabExcessHorizontalSpace = true;
		certificateChainViewer.getTree().setLayoutData(data);
		certificateChainViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
		certificateChainViewer.setContentProvider(new TreeNodeContentProvider());
		certificateChainViewer.setLabelProvider(new CertificateLabelProvider());
		certificateChainViewer.addSelectionChangedListener(getChainSelectionListener());
		if (inputElement instanceof Object[]) {
			ISelection selection = null;
			Object[] nodes = (Object[]) inputElement;
			if (nodes.length > 0) {
				selection = new StructuredSelection(nodes[0]);
				certificateChainViewer.setInput(new TreeNode[] { (TreeNode) nodes[0] });
				selectedCertificate = nodes[0];
			}
			listViewer.setSelection(selection);
		}
		listViewer.addDoubleClickListener(getDoubleClickListener());
		listViewer.addSelectionChangedListener(getParentSelectionListener());
		createButtons(composite);
		return composite;
	}

	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, ProvUIMessages.TrustCertificateDialog_AcceptSelectedButtonLabel,
				true);
		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
		super.getOkButton().setEnabled(false);
	}

	private void createButtons(Composite composite) {
		Composite buttonComposite = new Composite(composite, SWT.NONE);
		buttonComposite.setLayout(new RowLayout());
		// Details button to view certificate chain
		detailsButton = new Button(buttonComposite, SWT.NONE);
		detailsButton.setText(ProvUIMessages.TrustCertificateDialog_Details);
		detailsButton.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				Object o = selectedCertificate;
				if (selectedCertificate instanceof TreeNode) {
					o = ((TreeNode) selectedCertificate).getValue();
				}
				if (o instanceof X509Certificate) {
					X509Certificate cert = (X509Certificate) o;
					X509CertificateViewDialog certificateDialog = new X509CertificateViewDialog(getShell(), cert);
					certificateDialog.open();
				}
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				widgetDefaultSelected(e);
			}
		});

		Button exportButton = new Button(buttonComposite, SWT.NONE);
		exportButton.setText(ProvUIMessages.TrustCertificateDialog_Export);
		exportButton.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				Object o = selectedCertificate;
				if (selectedCertificate instanceof TreeNode) {
					o = ((TreeNode) selectedCertificate).getValue();
				}
				if (o instanceof X509Certificate) {
					X509Certificate cert = (X509Certificate) o;
					FileDialog destination = new FileDialog(detailsButton.getShell(), SWT.SAVE);
					destination.setFilterExtensions(new String[] { "*.der" }); //$NON-NLS-1$
					destination.setText(ProvUIMessages.TrustCertificateDialog_Export);
					String path = destination.open();
					if (path == null) {
						return;
					}
					File destinationFile = new File(path);
					try (FileOutputStream output = new FileOutputStream(destinationFile)) {
						output.write(cert.getEncoded());
					} catch (IOException | CertificateEncodingException ex) {
						ProvUIActivator.getDefault().getLog()
								.log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex));
					}
				}
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				widgetDefaultSelected(e);
			}
		});
	}

	private Composite createUpperDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);
		initializeDialogUnits(composite);
		createMessageArea(composite);

		listViewer = CheckboxTableViewer.newCheckList(composite, SWT.BORDER);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.heightHint = SIZING_SELECTION_WIDGET_HEIGHT;
		data.widthHint = SIZING_SELECTION_WIDGET_WIDTH;
		listViewer.getTable().setLayoutData(data);

		listViewer.setLabelProvider(labelProvider);
		listViewer.setContentProvider(contentProvider);

		addSelectionButtons(composite);

		listViewer.setInput(inputElement);

		if (!getInitialElementSelections().isEmpty()) {
			checkInitialSelections();
		}

		Dialog.applyDialogFont(composite);

		return composite;
	}

	/**
	 * Visually checks the previously-specified elements in this dialog's list
	 * viewer.
	 */
	private void checkInitialSelections() {
		Iterator<?> itemsToCheck = getInitialElementSelections().iterator();
		while (itemsToCheck.hasNext()) {
			listViewer.setChecked(itemsToCheck.next(), true);
		}
	}

	/**
	 * Add the selection and deselection buttons to the dialog.
	 *
	 * @param composite org.eclipse.swt.widgets.Composite
	 */
	private void addSelectionButtons(Composite composite) {
		Composite buttonComposite = new Composite(composite, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 0;
		layout.marginWidth = 0;
		layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
		buttonComposite.setLayout(layout);
		buttonComposite.setLayoutData(new GridData(SWT.END, SWT.TOP, true, false));

		Button selectButton = createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID,
				ProvUIMessages.TrustCertificateDialog_SelectAll, false);

		SelectionListener listener = widgetSelectedAdapter(e -> {
			listViewer.setAllChecked(true);
			getOkButton().setEnabled(true);
		});
		selectButton.addSelectionListener(listener);

		Button deselectButton = createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID,
				ProvUIMessages.TrustCertificateDialog_DeselectAll, false);

		listener = widgetSelectedAdapter(e -> {
			listViewer.setAllChecked(false);
			getOkButton().setEnabled(false);
		});
		deselectButton.addSelectionListener(listener);
	}

	private ISelectionChangedListener getChainSelectionListener() {
		return event -> {
			ISelection selection = event.getSelection();
			if (selection instanceof StructuredSelection) {
				selectedCertificate = ((StructuredSelection) selection).getFirstElement();
			}
		};
	}

	public TreeViewer getCertificateChainViewer() {
		return certificateChainViewer;
	}

	private IDoubleClickListener getDoubleClickListener() {
		return event -> {
			StructuredSelection selection = (StructuredSelection) event.getSelection();
			Object selectedElement = selection.getFirstElement();
			if (selectedElement instanceof TreeNode) {
				TreeNode treeNode = (TreeNode) selectedElement;
				// create and open dialog for certificate chain
				X509CertificateViewDialog certificateViewDialog = new X509CertificateViewDialog(getShell(),
						(X509Certificate) treeNode.getValue());
				certificateViewDialog.open();
			}
		};
	}

	private ISelectionChangedListener getParentSelectionListener() {
		return event -> {
			ISelection selection = event.getSelection();
			if (selection instanceof StructuredSelection) {
				TreeNode firstElement = (TreeNode) ((StructuredSelection) selection).getFirstElement();
				getCertificateChainViewer().setInput(new TreeNode[] { firstElement });
				getOkButton().setEnabled(listViewer.getChecked(firstElement));
				getCertificateChainViewer().refresh();
			}
		};
	}

	/**
	 * The <code>ListSelectionDialog</code> implementation of this
	 * <code>Dialog</code> method builds a list of the selected elements for later
	 * retrieval by the client and closes this dialog.
	 */
	@Override
	protected void okPressed() {
		// Get the input children.
		Object[] children = contentProvider.getElements(inputElement);

		// Build a list of selected children.
		if (children != null) {
			ArrayList<Object> list = new ArrayList<>();
			for (Object element : children) {
				if (listViewer.getChecked(element)) {
					list.add(element);
				}
			}
			setResult(list);
		}
		super.okPressed();
	}
}
