package io.jenkins.docker.pipeline;

import com.google.common.collect.ImmutableSet;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.Computer;
import hudson.model.Node;
import hudson.model.TaskListener;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.steps.Step;
import org.jenkinsci.plugins.workflow.steps.StepContext;
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
import org.jenkinsci.plugins.workflow.steps.StepExecution;
import org.kohsuke.stapler.DataBoundConstructor;

import javax.annotation.Nonnull;
import java.util.Set;

/**
 * @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
 */
public class DockerNodeStep extends Step {

    private String dockerHost;

    private String credentialsId;

    private String image;

    private String remoteFs;

    @DataBoundConstructor
    public DockerNodeStep(String dockerHost, String credentialsId, String image, String remoteFs) {
        this.dockerHost = dockerHost;
        this.credentialsId = credentialsId;
        this.image = image;
        this.remoteFs = remoteFs;
    }

    public String getDockerHost() {
        return dockerHost;
    }

    public String getCredentialsId() {
        return credentialsId;
    }

    public String getImage() {
        return image;
    }

    public String getRemoteFs() {
        return remoteFs;
    }


    @Override
    public StepExecution start(StepContext context) throws Exception {
        return new DockerNodeStepExecution(context, dockerHost, credentialsId, image, remoteFs);
    }

    @Extension(optional = true)
    public static class DescriptorImpl extends StepDescriptor {

        @Override
        public String getFunctionName() {
            return "dockerNode";
        }

        @Nonnull
        @Override
        public String getDisplayName() {
            return "(\uD83D\uDEA7) Docker Node";
        }


        @Override public boolean takesImplicitBlockArgument() {
            return true;
        }

        @Override
        public Set<? extends Class<?>> getRequiredContext() {
            return ImmutableSet.of(TaskListener.class, FlowNode.class);
        }

        @Override public Set<? extends Class<?>> getProvidedContext() {
            // TODO can/should we provide Executor? We cannot access Executor.start(WorkUnit) from outside the package. cf. isAcceptingTasks, withContexts
            return ImmutableSet.of(Computer.class, FilePath.class, /* DefaultStepContext infers from Computer: */ Node.class, Launcher.class);
        }
    }

}

@@ -176,24 +176,50 @@
 l.Computer;%0A
+import hudson.model.Item;%0A
 import hudso
@@ -228,24 +228,24 @@
 model.Node;%0A
-
 import hudso
@@ -262,24 +262,165 @@
 skListener;%0A
+import hudson.util.ListBoxModel;%0Aimport jenkins.model.Jenkins;%0Aimport org.jenkinsci.plugins.docker.commons.credentials.DockerServerEndpoint;%0A
 import org.j
@@ -683,24 +683,67 @@
 pExecution;%0A
+import org.kohsuke.stapler.AncestorInPath;%0A
 import org.k
@@ -778,16 +778,59 @@
 tructor;
+%0Aimport org.kohsuke.stapler.QueryParameter;
 %0A%0Aimport
@@ -2168,35 +2168,390 @@
 rn %22
-(%5CuD83D%5CuDEA7) Docker Node%22
+Docker Node (%E2%9A%A0%EF%B8%8F Experimental)%22;%0A        %7D%0A%0A        public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item item, @QueryParameter String uri) %7B%0A            DockerServerEndpoint.DescriptorImpl descriptor = (DockerServerEndpoint.DescriptorImpl) Jenkins.getInstance().getDescriptor(DockerServerEndpoint.class);%0A            return descriptor.doFillCredentialsIdItems(item, uri)
 ;%0A  

fix snippet generator for dockerNode