package com.amazon.jenkins.ec2fleet;

import hudson.model.Computer;
import hudson.model.Node;
import hudson.slaves.RetentionStrategy;
import hudson.slaves.SlaveComputer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * User: cyberax
 * Date: 1/12/16
 * Time: 02:56
 */
public class IdleRetentionStrategy extends RetentionStrategy<SlaveComputer>
{
    private final int maxIdleMinutes;
    private final EC2FleetCloud parent;

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

    public IdleRetentionStrategy(final EC2FleetCloud parent) {
        this.maxIdleMinutes = parent.getIdleMinutes();
        this.parent = parent;
        LOGGER.log(Level.INFO, "Idle Retention initiated");
    }

    protected boolean isIdleForTooLong(final Computer c) {
        boolean isTooLong = false;
        if(maxIdleMinutes != null) {
            long age = System.currentTimeMillis()-c.getIdleStartMilliseconds();
            long maxAge = maxIdleMinutes*60*1000;
            LOGGER.log(Level.FINE, "Instance: " + c.getDisplayName() + " Age: " + age + " Max Age:" + maxAge);
            isTooLong = age > maxAge;
        }
        return isTooLong;
    }

    @Override public long check(final SlaveComputer c) {
        // Ensure that the EC2FleetCloud cannot be mutated from under us while
        // we're doing this check
        synchronized(parent) {
            // Ensure nobody provisions onto this node until we've done
            // checking
            boolean shouldAcceptTasks = c.isAcceptingTasks();
            c.setAcceptingTasks(false);
            try {
                if (isIdleForTooLong(c)) {
                    // Find instance ID
                    Node compNode = c.getNode();
                    if (compNode == null) {
                        return 0;
                    }

                    final String nodeId = compNode.getNodeName();
                    if (parent.terminateInstance(nodeId)) {
                        // Instance successfully terminated, so no longer accept tasks
                        shouldAcceptTasks = false;
                    }
                }
            } finally {
                c.setAcceptingTasks(shouldAcceptTasks);
            }
        }

        return 1;
    }

    @Override public void start(SlaveComputer c) {
        LOGGER.log(Level.INFO, "Connecting to instance: " + c.getDisplayName());
        c.connect(false);
    }
}

@@ -402,16 +402,59 @@
 inutes;%0A
+    private final boolean alwaysReconnect;%0A
     priv
@@ -699,24 +699,86 @@
 eMinutes();%0A
+        this.alwaysReconnect = parent.isAlwaysReconnectSet();%0A
         this
@@ -2243,32 +2243,274 @@
               %7D%0A
+                %7D else if (alwaysReconnect && c.isOffline() && !c.isConnecting() && c.isLaunchSupported()) %7B%0A                    LOGGER.log(Level.INFO, %22Reconnecting to instance: %22 + c.getDisplayName());%0A                    c.tryReconnect();%0A
                 

implement alwaysReconnect