/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed 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 com.motorolamobility.studio.android.certmanager.core;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.eclipse.equinox.security.storage.ISecurePreferences;
import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
import org.eclipse.equinox.security.storage.StorageException;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
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.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

import com.motorola.studio.android.common.log.StudioLogger;
import com.motorola.studio.android.common.utilities.EclipseUtils;
import com.motorolamobility.studio.android.certmanager.CertificateManagerActivator;
import com.motorolamobility.studio.android.certmanager.exception.KeyStoreManagerException;
import com.motorolamobility.studio.android.certmanager.i18n.CertificateManagerNLS;

/**
 *	This class is responsible to retrieve passwords for a keystore and its entries.
 *	Usage:
 *  Instantiate with a keyStoreFile, call the methods getPassword.
 *  If needed a dialog will be shown, asking user to type the password.
 */
public class PasswordProvider
{

    private static final String PREF_ROOT_NODE = CertificateManagerActivator.PLUGIN_ID
            + "_passwords"; //$NON-NLS-1$

    private static final String KS_PASSWORD_KEY = "KS_PASSWORD"; //$NON-NLS-1$

    private final class KeyStorePasswdDialog extends Dialog
    {
        private final File keyStoreFile;

        private String passwd;

        private boolean savePasswd;

        private Text paswordText;

        private Button saveCheckBox;

        private final String alias;

        private KeyStorePasswdDialog(Shell parentShell, File keyStoreFile, String alias)
        {
            super(parentShell);
            this.keyStoreFile = keyStoreFile;
            this.alias = alias;
        }

        @Override
        protected Control createDialogArea(Composite parent)
        {

            Composite mainComposite = new Composite(parent, SWT.NONE);
            GridLayout gridLayout = new GridLayout(2, false);
            mainComposite.setLayout(gridLayout);

            //Creates the message
            Label messageLabel = new Label(mainComposite, SWT.NONE);
            GridData gridData = new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 2);
            messageLabel.setLayoutData(gridData);

            if (this.alias.equals(KS_PASSWORD_KEY))
            {
                getShell().setText(CertificateManagerNLS.PasswordProvider_DialogTitle);
                messageLabel.setText(NLS.bind(CertificateManagerNLS.PasswordProvider_MessageLabel,
                        keyStoreFile.getName()));
            }
            else
            {
                getShell().setText(CertificateManagerNLS.CertificateBlock_KeyPassword_Label);
                messageLabel.setText(NLS.bind(
                        CertificateManagerNLS.PasswordProvider_Key_MessageLabel, alias));
            }

            //Creates the text field label
            Label passwdLabel = new Label(mainComposite, SWT.NONE);
            gridData = new GridData(SWT.LEFT, SWT.CENTER, false, false);
            passwdLabel.setLayoutData(gridData);
            passwdLabel.setText(CertificateManagerNLS.PasswordProvider_PasswordLabel);

            //Creates the password text
            paswordText = new Text(mainComposite, SWT.BORDER | SWT.PASSWORD);
            gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
            paswordText.setLayoutData(gridData);

            //Creates the save password checkbox
            saveCheckBox = new Button(mainComposite, SWT.CHECK);
            saveCheckBox.setText(CertificateManagerNLS.PasswordProvider_SaveThisPassword);
            saveCheckBox.setSelection(false);
            gridData = new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1);
            saveCheckBox.setLayoutData(gridData);
            saveCheckBox.setVisible(KeyStoreManager.getInstance().isKeystoreMapped(keyStoreFile));

            return super.createDialogArea(parent);
        }

        @Override
        protected void okPressed()
        {
            passwd = paswordText.getText();
            savePasswd = saveCheckBox.getSelection();
            super.okPressed();
        }

        public String getPasswd()
        {
            return passwd;
        }

        public boolean mustSavePasswd()
        {
            return savePasswd;
        }
    }

    private final File keyStoreFile;

    private final ISecurePreferences securePreferences;

    private boolean canSavePassword = true;

    public PasswordProvider(File keyStoreFile)
    {
        this(keyStoreFile, KeyStoreManager.getInstance().isKeystoreMapped(keyStoreFile));
    }

    public PasswordProvider(File keyStoreFile, boolean canSavePassword)
    {
        this.keyStoreFile = keyStoreFile;
        this.securePreferences = SecurePreferencesFactory.getDefault();
        this.canSavePassword = canSavePassword;
    }

    /**
     * Retrieves the KeyStore password.
     * @param promptPassword whether the password entry dialog will be shown or not 
     * @param useSavedPassword whether to use the keyStore saved password
     * @return the password string or null if user canceled the dialog
     * @throws KeyStoreManagerException 
     */
    public String getKeyStorePassword(boolean promptPassword, boolean useSavedPassword)
            throws KeyStoreManagerException
    {
        return getPassword(KS_PASSWORD_KEY, promptPassword, useSavedPassword);
    }

    /**
     * Retrieves the KeyStore password.
     * This method will always attempt to retrieve the saved password.
     * It's behavior is the same as of calling the method getPassword(promptPassword, true)
     * @param promptPassword whether the password entry dialog will be shown or not 
     * @return the password string or null if user canceled the dialog
     * @throws KeyStoreManagerException 
     */
    public String getKeyStorePassword(boolean promptPassword) throws KeyStoreManagerException
    {
        return getPassword(KS_PASSWORD_KEY, promptPassword, true);
    }

    /**
     * Retrieves the password for a given alias within a keyStore.
     * This method will always attempt to retrieve the saved password.
     * It's behavior is the same as of calling the method getPassword(promptPassword, true)
     * @param promptPassword whether the password entry dialog will be shown or not 
     * @return the password string or null if user canceled the dialog
     * @throws KeyStoreManagerException 
     */
    public String getPassword(String alias, boolean promptPassword) throws KeyStoreManagerException
    {
        return getPassword(alias, promptPassword, true);
    }

    /**
     * Retrieves the password for a given alias within a keyStore.
     * This method will always attempt to retrieve the saved password.
     * It's behavior is the same as of calling the method getPassword(promptPassword, true)
     * @param promptPassword whether the password entry dialog will be shown or not 
     * @param useSavedPassword whether to use the keyStore saved password
     * @return the password string or null if user canceled the dialog
     * @throws KeyStoreManagerException 
     */
    public String getPassword(String alias, boolean promptPassword, boolean useSavedPassword)
            throws KeyStoreManagerException
    {
        String password = null;

        if (useSavedPassword)
        {
            if (securePreferences != null)
            {
                String prefKey = alias;
                password = getSavedPasswd(prefKey);
            }
            else
            {
                throw new KeyStoreManagerException(
                        CertificateManagerNLS.PasswordProvider_Error_WhileSaving);
            }
        }

        if ((password == null) && promptPassword)
        {
            password = promptPassword(alias);
        }

        return password;
    }

    private String getSavedPasswd(String prefKey)
    {
        String password = null;
        // Try to get the password from secure storage
        if (securePreferences.nodeExists(PREF_ROOT_NODE))
        {
            ISecurePreferences node = securePreferences.node(PREF_ROOT_NODE);
            try
            {
                if (node.nodeExists(keyStoreFile.getAbsolutePath()))
                {
                    ISecurePreferences ksNode = node.node(keyStoreFile.getAbsolutePath());
                    password = ksNode.get(prefKey, null);
                }
            }
            catch (StorageException e)
            {
                //Do nothing, password will be null.
            }
        }
        return password;
    }

    private String promptPassword(final String alias) throws KeyStoreManagerException
    {
        final String[] result = new String[1];
        final Boolean[] canProceed = new Boolean[1];

        Display.getDefault().syncExec(new Runnable()
        {
            @Override
            public void run()
            {
                KeyStorePasswdDialog dialog =
                        new KeyStorePasswdDialog(PlatformUI.getWorkbench()
                                .getModalDialogShellProvider().getShell(), keyStoreFile, alias);

                int diagStatus = dialog.open();

                if (diagStatus == Dialog.OK)
                {
                    //Read the values from the dialog and do the actions, return passwd and save if required
                    result[0] = dialog.getPasswd();

                    canSavePassword = KeyStoreManager.getInstance().isKeystoreMapped(keyStoreFile);
                    canProceed[0] = dialog.mustSavePasswd();
                }
                else
                {
                    //dialog cancelled
                    canProceed[0] = false;
                    result[0] = null;
                }
            }
        });

        if (canProceed[0] && canSavePassword)
        {
            if (securePreferences != null)
            {
                savePassword(alias, result[0]);
            }
            else
            {
                EclipseUtils.showWarningDialog(CertificateManagerNLS.PasswordProvider_DialogTitle,
                        CertificateManagerNLS.PasswordProvider_Error_WhileSaving);
            }
        }

        return result[0];
    }

    public void saveKeyStorePassword(String password) throws KeyStoreManagerException
    {
        savePassword(KS_PASSWORD_KEY, password);
    }

    public void savePassword(final String alias, String password) throws KeyStoreManagerException
    {
        String prefKey;
        canSavePassword = KeyStoreManager.getInstance().isKeystoreMapped(keyStoreFile);
        if (canSavePassword) //protect from saving 
        {
            if (alias != null)
            {
                prefKey = alias;
            }
            else
            {
                prefKey = KS_PASSWORD_KEY;
            }

            ISecurePreferences rootNode = securePreferences.node(PREF_ROOT_NODE);
            try
            {
                ISecurePreferences ksNode = rootNode.node(keyStoreFile.getAbsolutePath());
                ksNode.put(prefKey, password, true);
                ksNode.flush();
            }
            catch (Exception e)
            {
                throw new KeyStoreManagerException(
                        CertificateManagerNLS.PasswordProvider_Error_WhileSaving);
            }
        }
    }

    /**
     * Deletes the entire node (including KS_PASSWORD_KEY and children aliases)
     * @throws KeyStoreManagerException
     */
    public void deleteKeyStoreSavedPasswordNode() throws KeyStoreManagerException
    {
        deleteSavedPassword(null);
    }

    /** 
     * Deletes only KS_PASSWORD_KEY (not children aliases) 
     */
    public void deleteKeyStoreSavedPassword() throws KeyStoreManagerException
    {
        deleteSavedPassword(KS_PASSWORD_KEY);
    }

    public void deleteSavedPassword(String alias) throws KeyStoreManagerException
    {

        ISecurePreferences ksNode = getKeyStoreNode();
        if (ksNode != null)
        {
            if (alias == null)
            {
                ksNode.removeNode();
            }
            else
            {
                ksNode.remove(alias);
                //if no item has no child, then we can remove the node
                if (ksNode.keys().length == 0)
                {
                    ksNode.removeNode();
                }
            }

            try
            {
                ksNode.flush();
            }
            catch (IllegalStateException e)
            {
                //Do nothing, node has already been removed
            }
            catch (IOException e)
            {
                throw new KeyStoreManagerException(NLS.bind(
                        CertificateManagerNLS.PasswordProvider_Error_WhileRemovingPassword,
                        keyStoreFile.getName()));
            }
        }
    }

    /**
     * This method will remove all saved entries for this keystore file that is not listed on the aliasList.
     * The idea is to remove all saved passwords that makes reference to non-existant entries.
     * @param aliasList the list of alias to be kept if available on the security keystore
     * @throws KeyStoreManagerException if writing the security keystore fails for some reason
     */
    public void cleanModel(List<String> aliasList) throws KeyStoreManagerException
    {
        ISecurePreferences keyStoreNode = getKeyStoreNode();
        if (keyStoreNode != null)
        {
            String[] savedKeys = keyStoreNode.keys();
            for (String savedAlias : savedKeys)
            {
                if (!savedAlias.equals(KS_PASSWORD_KEY) && !aliasList.contains(savedAlias))
                {
                    keyStoreNode.remove(savedAlias);
                }
            }
            try
            {
                keyStoreNode.flush();
            }
            catch (IOException e)
            {
                throw new KeyStoreManagerException(NLS.bind(
                        CertificateManagerNLS.PasswordProvider_Error_WhileRemovingPassword,
                        keyStoreFile.getName()));
            }
        }
    }

    /*
     * @return the keystore node if it exists
     */
    private ISecurePreferences getKeyStoreNode()
    {
        ISecurePreferences ksNode = null;
        if (securePreferences.nodeExists(PREF_ROOT_NODE))
        {
            ISecurePreferences rootNode = securePreferences.node(PREF_ROOT_NODE);

            if (rootNode.nodeExists(keyStoreFile.getAbsolutePath()))
            {
                ksNode = rootNode.node(keyStoreFile.getAbsolutePath());
            }
        }
        return ksNode;
    }

    /**
     * If keystore password is saved.
     */
    public boolean isPasswordSaved()
    {
        return isPasswordSaved(KS_PASSWORD_KEY);
    }

    /**
     * If alias password is saved.
     */
    public boolean isPasswordSaved(String prefKey)
    {
        ISecurePreferences ksNode = null;
        boolean isSaved = false;
        if (securePreferences.nodeExists(PREF_ROOT_NODE))
        {
            ISecurePreferences rootNode = securePreferences.node(PREF_ROOT_NODE);
            ksNode = rootNode.node(keyStoreFile.getAbsolutePath());
            try
            {
                String value = ksNode.get(prefKey, null);
                isSaved = value != null; //password is saved if it is not the default value (because password length should be at least 6
            }
            catch (StorageException e)
            {
                StudioLogger.debug("It was not possible to get if the " + prefKey
                        + " is saved or not");
                isSaved = false;
            }
        }
        return isSaved;
    }
}
