package org.csanchez.jenkins.plugins.kubernetes;

import hudson.Extension;
import hudson.model.TaskListener;
import hudson.model.Descriptor;
import hudson.model.Node;
import hudson.slaves.AbstractCloudSlave;
import hudson.slaves.NodeProperty;
import hudson.slaves.ComputerLauncher;
import hudson.slaves.JNLPLauncher;

import java.io.IOException;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jenkinsci.plugins.durabletask.executors.OnceRetentionStrategy;
import org.kohsuke.stapler.DataBoundConstructor;

import com.github.kubernetes.java.client.model.Pod;
import com.google.common.base.MoreObjects;
import com.nirima.jenkins.plugins.docker.DockerTemplate;

/**
 * @author Carlos Sanchez <carlos@apache.org>
 */
public class KubernetesSlave extends AbstractCloudSlave {

    private static final Logger LOGGER = Logger.getLogger(KubernetesSlave.class.getName());

    private static final long serialVersionUID = -8642936855413034232L;

    public final Pod pod;

    @DataBoundConstructor
    public KubernetesSlave(Pod pod, DockerTemplate template, String nodeDescription) throws Descriptor.FormException,
            IOException {
        super(pod.getId(), nodeDescription, "/", template.getNumExecutors(), Node.Mode.NORMAL, pod.getLabels()
                .getName(), getLauncher(pod), new OnceRetentionStrategy(0), Collections
                .<NodeProperty<Node>> emptyList());

        this.pod = pod;
    }

    private static ComputerLauncher getLauncher(Pod pod) {
        return new JNLPLauncher();
    }

    @Override
    public KubernetesComputer createComputer() {
        return new KubernetesComputer(this);
    }

    @Override
    protected void _terminate(TaskListener listener) throws IOException, InterruptedException {
        LOGGER.log(Level.INFO, "Terminating Kubernetes instance for slave " + name);

        try {
            toComputer().disconnect(null);
            // TODO

        } catch (Exception e) {
            LOGGER.log(Level.SEVERE, "Failure to terminate instance for slave " + name, e);
        }
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this).add("name", name).toString();
    }

    @Extension
    public static final class DescriptorImpl extends SlaveDescriptor {

        @Override
        public String getDisplayName() {
            return "Kubernetes Slave";
        };

        @Override
        public boolean isInstantiable() {
            return false;
        }

    }
}

@@ -369,16 +369,54 @@
 ctions;%0A
+import java.util.concurrent.Callable;%0A
 import j
@@ -593,24 +593,84 @@
 nstructor;%0A%0A
+import com.github.kubernetes.java.client.exceptions.Status;%0A
 import com.g
@@ -1094,21 +1094,22 @@
 ;%0A%0A    p
-ublic
+rivate
  final P
@@ -1117,16 +1117,58 @@
 d pod;%0A%0A
+    private final KubernetesCloud cloud;%0A%0A
     @Dat
@@ -1268,17 +1268,52 @@
 cription
-)
+, KubernetesCloud cloud)%0A           
  throws 
@@ -1337,28 +1337,16 @@
 ception,
-%0A           
  IOExcep
@@ -1383,75 +1383,170 @@
 (), 
-nodeDescription, %22/%22, template.getNumExecutors(), Node.Mode.NORMAL,
+//%0A                nodeDescription, //%0A                %22/%22, //%0A                template.getNumExecutors(), //%0A                Node.Mode.NORMAL, //%0A               
  pod
@@ -1557,16 +1557,30 @@
 Labels()
+.getName(), //
 %0A       
@@ -1591,20 +1591,8 @@
     
- .getName(),
  get
@@ -1605,16 +1605,35 @@
 er(pod),
+ //%0A               
  new Onc
@@ -1655,27 +1655,18 @@
 egy(0), 
-Collections
+//
 %0A       
@@ -1674,16 +1674,27 @@
         
+Collections
 .%3CNodePr
@@ -1746,16 +1746,44 @@
  = pod;%0A
+        this.cloud = cloud;%0A
     %7D%0A%0A 
@@ -2177,27 +2177,29 @@
 e for slave 
-%22 +
+%7B0%7D%22,
  name);%0A%0A   
@@ -2221,16 +2221,163 @@
         
+cloud.connect().deletePod(this.pod.getId());%0A            LOGGER.log(Level.INFO, %22Terminated Kubernetes instance for slave %7B0%7D%22, name);%0A            
 toComput
@@ -2402,29 +2402,8 @@
 ll);
-%0A            // TODO%0A
 %0A   

Implement slave._terminate