package org.jenkinsci.plugins.terraform;


import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Functions;
import hudson.Extension;

import hudson.remoting.Callable;

import hudson.model.Node;
import hudson.model.TaskListener;

import hudson.tools.ToolProperty;
import hudson.tools.ToolInstaller;
import hudson.tools.ToolDescriptor;
import hudson.tools.ToolInstallation;

import jenkins.model.Jenkins;

import org.kohsuke.stapler.DataBoundConstructor;

import java.util.List;
import java.util.Collections;

import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;




public class TerraformInstallation extends ToolInstallation {

    private static final String UNIX_EXECUTABLE = "terraform";
    private static final String WINDOWS_EXECUTABLE = "terraform.exe";


    @DataBoundConstructor
    public TerraformInstallation(String name, String home, List<? extends ToolProperty<?>> properties) {
        super(name, home, properties);
    }


    public TerraformInstallation forNode(Node node, TaskListener log) throws IOException, InterruptedException {
        return new TerraformInstallation(getName(), translateFor(node, log), getProperties().toList());
    }


    public TerraformInstallation forEnvironment(EnvVars environment) {
        return new TerraformInstallation(getName(), environment.expand(getHome()), getProperties().toList());
    }

    
    public String getExecutablePath(final Launcher launcher) throws IOException, InterruptedException {
        return launcher.getChannel().call(new Callable<String, IOException>() {
            public String call() throws IOException {

                FilePath homeDirectory = new FilePath(new File(getHome()));

                try {
                    if (!(homeDirectory.exists() && homeDirectory.isDirectory())) 
                        throw new FileNotFoundException(Messages.HomeDirectoryNotFound(homeDirectory));
                } catch (InterruptedException ex) {
                    throw new IOException(ex);
                }

                FilePath executable = new FilePath(homeDirectory, getExecutableFilename());

                try {
                    if (!executable.exists())
                        throw new FileNotFoundException(Messages.ExecutableNotFound(homeDirectory));
                } catch (InterruptedException ex) {
                    throw new IOException(ex);
                }

                return executable.getRemote();
            }
        });
    }


    protected String getExecutableFilename() {
        return Functions.isWindows() ? WINDOWS_EXECUTABLE : UNIX_EXECUTABLE;
    } 


    @Extension
    public static class DescriptorImpl extends ToolDescriptor<TerraformInstallation> {
    
        @Override
        public String getDisplayName() {
            return "Terraform";
        }


        @Override
        public List<? extends ToolInstaller> getDefaultInstallers() {
            return Collections.singletonList(new TerraformInstaller(null));
        }


        @Override
        public TerraformInstallation[] getInstallations() {
            return Jenkins.getInstance().getDescriptorByType(TerraformBuildWrapper.DescriptorImpl.class).getInstallations();
        }


        @Override
        public void setInstallations(TerraformInstallation... installations) {
            Jenkins.getInstance().getDescriptorByType(TerraformBuildWrapper.DescriptorImpl.class).setInstallations(installations);
        }
    }
}

@@ -251,16 +251,57 @@
 istener;
+%0Aimport hudson.model.EnvironmentSpecific;
 %0A%0Aimport
@@ -434,24 +434,60 @@
 tallation;%0A%0A
+import hudson.slaves.NodeSpecific;%0A%0A
 import jenki
@@ -630,16 +630,45 @@
 o.File;%0A
+import java.io.Serializable;%0A
 import j
@@ -785,25 +785,184 @@
 nstallation 
-%7B
+implements EnvironmentSpecific%3CTerraformInstallation%3E, NodeSpecific%3CTerraformInstallation%3E, Serializable %7B%0A%0A    private static final long serialVersionUID = 1L;
 %0A%0A    privat

Fix for #5, #6 implementing EnvironmentSpecific, NodeSpecific