package org.jenkinsci.plugins.credentialsbinding.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.jenkinsci.plugins.credentialsbinding.BindingDescriptor;
import org.jenkinsci.plugins.credentialsbinding.MultiBinding;
import org.kohsuke.stapler.DataBoundConstructor;

import com.cloudbees.plugins.credentials.common.StandardCertificateCredentials;

import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.Run;
import hudson.model.TaskListener;

public class CertificateMultiBinding extends MultiBinding<StandardCertificateCredentials> {

	private final String keystoreVariable;

	public String getKeystoreVariable() {
		return keystoreVariable;
	}

	public String getPasswordVariable() {
		return passwordVariable;
	}

	public String getAliasVariable() {
		return aliasVariable;
	}

	private final String passwordVariable;
	private final String aliasVariable;

	@DataBoundConstructor
	public CertificateMultiBinding(String keystoreVariable, String passwordVariable, String aliasVariable,
			String credentialsId) {
		super(credentialsId);
		this.keystoreVariable = keystoreVariable;
		this.passwordVariable = passwordVariable;
		this.aliasVariable = aliasVariable;
	}

	@Override
	protected Class<StandardCertificateCredentials> type() {
		return StandardCertificateCredentials.class;
	}

	@Override
	public org.jenkinsci.plugins.credentialsbinding.MultiBinding.MultiEnvironment bind(Run<?, ?> build,
			FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException {
		StandardCertificateCredentials credentials = getCredentials(build);
		final String storePassword = credentials.getPassword().getPlainText();
		Map<String, String> m = new HashMap<String, String>();
		m.put(aliasVariable, credentials.getDescription());
		m.put(passwordVariable, storePassword);

		if (workspace != null) {
			FilePath secrets = FileBinding.secretsDir(workspace);
			String tempKeyStoreName = UUID.randomUUID().toString();
			final FilePath secret = secrets.child(tempKeyStoreName);
			OutputStream out = secret.write();
			try {
				credentials.getKeyStore().store(out, storePassword.toCharArray());
			} catch (KeyStoreException e) {
				throw new IOException(e);
			} catch (NoSuchAlgorithmException e) {
				throw new IOException(e);
			} catch (CertificateException e) {
				throw new IOException(e);
			} finally {
				org.apache.commons.io.IOUtils.closeQuietly(out);
			}
			secret.chmod(0400);
			m.put(keystoreVariable, secret.getRemote());
			return new MultiEnvironment(m, new UnbinderImpl(tempKeyStoreName));
		} else {
			return new MultiEnvironment(m);
		}
	}

	private static class UnbinderImpl implements Unbinder {

		private static final long serialVersionUID = 1;

		private final String keyStoreName;

		UnbinderImpl(String dirName) {
			this.keyStoreName = dirName;
		}

		@Override
		public void unbind(Run<?, ?> build, FilePath workspace, Launcher launcher, TaskListener listener)
				throws IOException, InterruptedException {
			FileBinding.secretsDir(workspace).child(keyStoreName).delete();
		}

	}

	@Override
	public Set<String> variables() {
		return new HashSet<String>(Arrays.asList(keystoreVariable, passwordVariable, aliasVariable));
	}

	@Extension
	public static class DescriptorImpl extends BindingDescriptor<StandardCertificateCredentials> {

		@Override
		protected Class<StandardCertificateCredentials> type() {
			return StandardCertificateCredentials.class;
		}

		@Override
		public String getDisplayName() {
			return Messages.CertificateMultiBinding_certificate_keystore();
		}

	}

}

@@ -2293,24 +2293,30 @@
 space);%0D%0A%09%09%09
+final 
 String tempK
@@ -2953,32 +2953,22 @@
 derImpl(
-tempKeyStoreName
+secret
 ));%0D%0A%09%09%7D
@@ -3148,30 +3148,32 @@
 ivate final 
-String
+FilePath
  keyStoreNam
@@ -3169,19 +3169,19 @@
 keyStore
-Nam
+Fil
 e;%0D%0A%0D%0A%09%09
@@ -3197,21 +3197,28 @@
 mpl(
-String dirNam
+FilePath keystoreFil
 e) %7B
@@ -3239,21 +3239,26 @@
 tore
-Nam
+Fil
 e = 
-dirNam
+keystoreFil
 e;%0D%0A
@@ -3433,56 +3433,16 @@
 %0A%09%09%09
-FileBinding.secretsDir(workspace).child(
 keyStore
 Name
@@ -3437,21 +3437,20 @@
 keyStore
-Name)
+File
 .delete(

Use FilePath instead of unspecific String