/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2013. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
import iControl.CommonStatistic
import iControl.LocalLBNodeAddressNodeAddressStatisticEntry
import iControl.LocalLBNodeAddressNodeAddressStatistics
import iControl.ManagementPartitionBindingStub

import com.urbancode.air.AirPluginTool

final def apTool = new AirPluginTool(this.args[0], this.args[1])
def m_interfaces = new iControl.Interfaces()
final def props = apTool.getStepProperties()

final def serverUrlArray = props['serverURL']?.split('://') as String[]
final def username = props['username']
final def password = props['password']
final def nodeAddress = props['nodeAddress'] as String
final def partitionName = props['partition']
final def waitTime = (props['waitForConnections'])?Long.valueOf(props['waitForConnections']):0
final def sleepInterval = (props['sleepInterval'])?Long.valueOf(props['sleepInterval']):5
final def timeout = Integer.parseInt(props['timeout'])
final def forceOffline = Boolean.valueOf(props['forceOffline'])

def getActiveConnections = { nodeAddressBinding ->        
    def stats = nodeAddressBinding.get_all_statistics();
    def statsEntries = stats.getStatistics();
    for (statsEntry in statsEntries) {
        String nodeAddressToTest = statsEntry.getNode_address();
        if (nodeAddressToTest.equals(nodeAddress)){
            CommonStatistic[] comStats = statsEntry.getStatistics();
            for(CommonStatistic comStat : comStats) {
                if (comStat.getType().equals(iControl.CommonStatisticType.STATISTIC_SERVER_SIDE_CURRENT_CONNECTIONS)) {
                    return comStat.getValue().getLow();
                }
            }
        }
    }
}
def waitForConnections = { nodeAddressBinding ->
    def allowedTime = System.currentTimeMillis() + waitTime * 1000
    def currentConnections = getActiveConnections(nodeAddressBinding)
    while(currentConnections > 0) {
        if (System.currentTimeMillis() > allowedTime) {
            println "Allowed time for waiting for connections was exceeded. Bringing the node down now."
            return;
        }
        println("Waiting for $currentConnections to close, sleep for $sleepInterval second(s)")
        sleep(sleepInterval * 1000, {println("Waiting aborted!"); return true})
        currentConnections = getActiveConnections(nodeAddressBinding)
    }
    println("All connections closed for pool, done waiting.")
}

try {
    def connectionString = serverUrlArray.length > 1? serverUrlArray[1] : serverUrlArray[0]
    if (connectionString.endsWith('/'))
    connectionString = connectionString.substring(0, connectionString.length() - 1)

    //m_interfaces_initialize must be called to use its methods
    m_interfaces.initialize(connectionString, username, password)
    def partitionBinding = m_interfaces.getManagementPartition()
    partitionBinding.set_active_partition(partitionName)
    def nodeAddressBinding = m_interfaces.getLocalLBNodeAddress()
    
    String[] nodeAddressArray = [nodeAddress]
    iControl.CommonEnabledState[] disabledStatus = [iControl.CommonEnabledState.STATE_DISABLED]
    nodeAddressBinding.set_session_enabled_state(nodeAddressArray, disabledStatus)
    if (forceOffline) {
        nodeAddressBinding.set_monitor_state(nodeAddressArray, disabledStatus)
    }
    println "Node status was set to disabled."
    nodeAddressBinding.setTimeout(timeout * 1000)
    if (waitTime) {
        println "Beginning to wait for connections to close."
        waitForConnections(nodeAddressBinding)
    }
    println "Disabled node ${nodeAddress} across all pools and ports."
    
}
catch (Exception e) {
    e.printStackTrace()
    System.exit(1)
}
