/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.taverna.workbench.ui.credentialmanager;

import static java.awt.BorderLayout.CENTER;
import static java.awt.BorderLayout.SOUTH;
import static java.awt.BorderLayout.WEST;
import static java.awt.Font.PLAIN;
import static javax.swing.BoxLayout.Y_AXIS;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
import static javax.swing.JOptionPane.showMessageDialog;
import static javax.swing.ListSelectionModel.SINGLE_SELECTION;
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
import static org.apache.taverna.workbench.ui.credentialmanager.CMStrings.ALERT_TITLE;
import static org.apache.taverna.workbench.ui.credentialmanager.CMStrings.ERROR_TITLE;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.taverna.security.credentialmanager.CMException;
import org.apache.taverna.security.credentialmanager.DistinguishedNameParser;
import org.apache.taverna.workbench.helper.NonBlockedHelpEnabledDialog;

/**
 * Allows the user import a key pair from a PKCS #12 file (keystore).
 */
@SuppressWarnings("serial")
class NewKeyPairEntryDialog extends NonBlockedHelpEnabledDialog {
	//private static final Logger logger = Logger.getLogger(NewKeyPairEntryDialog.class);

	/** List of key pairs available for import */
	private JList<String> keyPairsJList;
	/** PKCS #12 keystore */
	private KeyStore pkcs12KeyStore;
	/** Private key part of the key pair chosen by the user for import */
	private Key privateKey;
	/** Certificate chain part of the key pair chosen by the user for import */
	private Certificate[] certificateChain;
	/** Key pair alias to be used for this entry in the Keystore */
	private String alias;
	private final DistinguishedNameParser dnParser;

	public NewKeyPairEntryDialog(JFrame parent, String title, boolean modal,
			KeyStore pkcs12KeyStore, DistinguishedNameParser dnParser)
			throws CMException {
		super(parent, title, modal);
		this.pkcs12KeyStore = pkcs12KeyStore;
		this.dnParser = dnParser;
		initComponents();
	}

	public NewKeyPairEntryDialog(JDialog parent, String title, boolean modal,
			KeyStore pkcs12KeyStore, DistinguishedNameParser dnParser)
			throws CMException {
		super(parent, title, modal);
		this.pkcs12KeyStore = pkcs12KeyStore;
		this.dnParser = dnParser;
		initComponents();
	}

	/**
	 * Get the private part of the key pair.
	 */
	public Key getPrivateKey() {
		return privateKey;
	}

	/**
	 * Get the certificate chain part of the key pair.
	 */
	public Certificate[] getCertificateChain() {
		return certificateChain;
	}

	/**
	 * Get the keystore alias of the key pair.
	 */
	public String getAlias() {
		return alias;
	}

	private void initComponents() throws CMException {
		// Instructions
		JLabel instructionsLabel = new JLabel("Select a key pair to import:");
		instructionsLabel.setFont(new Font(null, PLAIN, 11));
		instructionsLabel.setBorder(new EmptyBorder(5, 5, 5, 5));
		JPanel instructionsPanel = new JPanel(new BorderLayout());
		instructionsPanel.add(instructionsLabel, WEST);

		// Import button
		final JButton importButton = new JButton("Import");
		importButton.setEnabled(false);
		importButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				importPressed();
			}
		});

		// Certificate details button
		final JButton certificateDetailsButton = new JButton("Details");
		certificateDetailsButton.setEnabled(false);
		certificateDetailsButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				certificateDetailsPressed();
			}
		});

        // List to hold keystore's key pairs
		keyPairsJList = new JList<>();
		keyPairsJList.setSelectionMode(SINGLE_SELECTION);
		keyPairsJList.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent evt) {
				boolean enabled = keyPairsJList.getSelectedIndex() >= 0;
				importButton.setEnabled(enabled);
				certificateDetailsButton.setEnabled(enabled);
			}
		});

        // Put the key list into a scroll pane
		JScrollPane keyPairsScrollPane = new JScrollPane(keyPairsJList,
				VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
		keyPairsScrollPane.getViewport().setBackground(
				keyPairsJList.getBackground());
        
        JPanel keyPairsPanel = new JPanel();
        keyPairsPanel.setLayout(new BoxLayout(keyPairsPanel, Y_AXIS));
		keyPairsPanel.setBorder(new EmptyBorder(10, 10, 10, 10));

		instructionsPanel.setAlignmentY(LEFT_ALIGNMENT);
		keyPairsPanel.add(instructionsPanel);
		keyPairsScrollPane.setAlignmentY(LEFT_ALIGNMENT);
		keyPairsPanel.add(keyPairsScrollPane);

		// Cancel button
		final JButton cancelButton = new JButton("Cancel");
		cancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				cancelPressed();
			}
		});

		JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
		buttonsPanel.add(certificateDetailsButton);
		buttonsPanel.add(importButton);
		buttonsPanel.add(cancelButton);

		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(keyPairsPanel, CENTER);
		getContentPane().add(buttonsPanel, SOUTH);

		// Populate the list
		populateKeyPairList();

		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent evt) {
				closeDialog();
			}
		});

		setResizable(false);
		getRootPane().setDefaultButton(importButton);
		pack();
	}

	/**
	 * Populate the key pair list with the PKCS #12 keystore's key pair aliases.
	 */
	private void populateKeyPairList() throws CMException {
		try {
			List<String> keyPairAliases = new ArrayList<>();

			Enumeration<String> aliases = pkcs12KeyStore.aliases();
			while (aliases.hasMoreElements()) {
				String alias = aliases.nextElement();

				if (pkcs12KeyStore.isKeyEntry(alias)) {
					pkcs12KeyStore.getKey(alias, new char[] {});
					Certificate[] certs = pkcs12KeyStore
							.getCertificateChain(alias);
					if (certs != null && certs.length != 0)
						keyPairAliases.add(alias);
				}
			}

            if (!keyPairAliases.isEmpty()) {
                keyPairsJList.setListData(keyPairAliases.toArray(new String[0]));
                keyPairsJList.setSelectedIndex(0);
			} else
                // No key pairs were found - warn the user
				showMessageDialog(this,
						"No private key pairs were found in the file",
						ALERT_TITLE, WARNING_MESSAGE);
		} catch (GeneralSecurityException ex) {
            throw new CMException("Problem occured while reading the PKCS #12 file.",
                ex);
        }
    }

	/**
	 * Display the selected key pair's certificate.
	 */
	private void certificateDetailsPressed() {
		try {
			String alias = (String) keyPairsJList.getSelectedValue();

			// Convert the certificate object into an X509Certificate object.
			X509Certificate cert = dnParser.convertCertificate(pkcs12KeyStore
					.getCertificate(alias));

			ViewCertDetailsDialog viewCertificateDialog = new ViewCertDetailsDialog(
					this, "Certificate details", true, (X509Certificate) cert,
					null, dnParser);
			viewCertificateDialog.setLocationRelativeTo(this);
			viewCertificateDialog.setVisible(true);
		} catch (Exception ex) {
			showMessageDialog(this,
					"Failed to obtain certificate details to show",
					ALERT_TITLE, WARNING_MESSAGE);
			closeDialog();
		}
	}

	public void importPressed() {
		String alias = (String) keyPairsJList.getSelectedValue();
		try {
			privateKey = pkcs12KeyStore.getKey(alias, new char[] {});
			certificateChain = pkcs12KeyStore.getCertificateChain(alias);
			this.alias = alias;
		} catch (Exception ex) {
			showMessageDialog(
					this,
					"Failed to load the private key and certificate chain from the PKCS #12 file.",
					ERROR_TITLE, ERROR_MESSAGE);
		}

        closeDialog();
    }

	public void cancelPressed() {
		/*
		 * Set everything to null, just in case some of the values have been set
		 * previously and the user pressed 'cancel' after that.
		 */
		privateKey = null;
		certificateChain = null;
		closeDialog();
	}

	private void closeDialog() {
		setVisible(false);
		dispose();
	}

}
