// Path: yet-another-docker-plugin/src/main/java/com/github/kostyasha/yad/utils/DockerUtils.java
// public static void jenkinsAddNodeWithRetry(DockerSlaveSingle slave) throws IOException,
//         InterruptedException {
//     IOException lastException = null;
//     int retries = 6;
// 
//     while (retries >= 0) {
//         try {
//             Jenkins.getInstance().addNode(slave);
//             return;
//         } catch (IOException ex) {
//             lastException = ex;
//             if (retries <= 0) {
//                 throw ex;
//             }
//             LOG.trace("Failed to add DockerSlaveSingle node to Jenkins, retrying...", ex);
//             Thread.sleep(1000);
//         } finally {
//             retries--;
//         }
//     }
// 
//     throw lastException;
// }


import com.github.kostyasha.yad.connector.YADockerConnector;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractProject;
import hudson.model.Computer;
import hudson.model.Descriptor;
import hudson.model.Node;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.slaves.DelegatingComputerLauncher;
import hudson.tasks.BuildWrapperDescriptor;
import jenkins.model.Jenkins;
import jenkins.tasks.SimpleBuildWrapper;
import org.jenkinsci.Symbol;
import org.jenkinsci.plugins.cloudstats.CloudStatistics;
import org.jenkinsci.plugins.cloudstats.ProvisioningActivity;
import org.kohsuke.stapler.DataBoundConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.PrintStream;
import static com.github.kostyasha.yad.utils.DockerUtils.jenkinsAddNodeWithRetry;
import static java.util.Objects.isNull;
import static org.jenkinsci.plugins.cloudstats.CloudStatistics.ProvisioningListener.get;

    @CheckForNull
    public String getSlaveName() {
        return slaveName;
    }

    protected void setSlaveName(String slaveName) {
        this.slaveName = slaveName;
    }

    @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
    @Override
    public void setUp(Context context,
                      Run<?, ?> run,
                      FilePath workspace,
                      Launcher launcher,
                      TaskListener listener,
                      EnvVars initialEnvironment) throws IOException, InterruptedException {
        PrintStream logger = listener.getLogger();
        logger.println("Trying to setup env...");

        final ProvisioningActivity.Id activityId = new ProvisioningActivity.Id(
                run.getDisplayName(),
                getConfig().getDockerContainerLifecycle().getImage()
        );

        try {
            get().onStarted(activityId);
            final String futureName = "yadp" + activityId.getFingerprint();

// Path: yet-another-docker-plugin/src/main/java/com/github/kostyasha/yad/utils/DockerUtils.java
// public static void jenkinsAddNodeWithRetry(DockerSlaveSingle slave) throws IOException,
//         InterruptedException {
//     IOException lastException = null;
//     int retries = 6;
// 
//     while (retries >= 0) {
//         try {
//             Jenkins.getInstance().addNode(slave);
//             return;
//         } catch (IOException ex) {
//             lastException = ex;
//             if (retries <= 0) {
//                 throw ex;
//             }
//             LOG.trace("Failed to add DockerSlaveSingle node to Jenkins, retrying...", ex);
//             Thread.sleep(1000);
//         } finally {
//             retries--;
//         }
//     }
// 
//     throw lastException;
// }


// Path: yet-another-docker-plugin/src/main/java/com/github/kostyasha/yad/DockerSimpleBuildWrapper.java
import com.github.kostyasha.yad.connector.YADockerConnector;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractProject;
import hudson.model.Computer;
import hudson.model.Descriptor;
import hudson.model.Node;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.slaves.DelegatingComputerLauncher;
import hudson.tasks.BuildWrapperDescriptor;
import jenkins.model.Jenkins;
import jenkins.tasks.SimpleBuildWrapper;
import org.jenkinsci.Symbol;
import org.jenkinsci.plugins.cloudstats.CloudStatistics;
import org.jenkinsci.plugins.cloudstats.ProvisioningActivity;
import org.kohsuke.stapler.DataBoundConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.PrintStream;
import static com.github.kostyasha.yad.utils.DockerUtils.jenkinsAddNodeWithRetry;
import static java.util.Objects.isNull;
import static org.jenkinsci.plugins.cloudstats.CloudStatistics.ProvisioningListener.get;


    @CheckForNull
    public String getSlaveName() {
        return slaveName;
    }

    protected void setSlaveName(String slaveName) {
        this.slaveName = slaveName;
    }

    @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
    @Override
    public void setUp(Context context,
                      Run<?, ?> run,
                      FilePath workspace,
                      Launcher launcher,
                      TaskListener listener,
                      EnvVars initialEnvironment) throws IOException, InterruptedException {
        PrintStream logger = listener.getLogger();
        logger.println("Trying to setup env...");

        final ProvisioningActivity.Id activityId = new ProvisioningActivity.Id(
                run.getDisplayName(),
                getConfig().getDockerContainerLifecycle().getImage()
        );

        try {
            get().onStarted(activityId);
            final String futureName = "yadp" + activityId.getFingerprint();

            jenkinsAddNodeWithRetry(getDockerSlaveSingleWithRetry(run, activityId, futureName));