#!/usr/bin/env python2.3
# -*- python -*-
from __future__ import division

__version__ = "$Revision: 1.6 $"

import commands
import itertools
import os
import sys
import time

LSLOAD_CMDLINE = os.path.join(os.environ["LSF_BINDIR"], r"""lsload -E -I r1m:r15s:r15m:ut %s | awk '/ok|busy/ { print $0 }' | sed -e "s/*/ /g" | tr -s " " " " | sort -k 3n,6n -k 3,6 | head -n 1""")
LSRCP_CMD = os.path.join(os.environ["LSF_BINDIR"], "lsrcp")

COL_HOST = 0
COL_R1M = 2
COL_R15S = 3

RQUEUE_SOFTMAX = 1.0
RQUEUE_SOFTMAX_STEP = 0.2
RQUEUE_HARDMAX = 2.0

SOFT_SLEEP_TIME = 15
HARD_SLEEP_TIME = 60

def get_node(nodes_str):
    rqueue_softmax = RQUEUE_SOFTMAX
    
    for index in itertools.count(1):
        line = commands.getoutput(LSLOAD_CMDLINE % nodes_str)
        cols = line.split(" ")

        r1m = float(cols[COL_R1M])
        r15s = float(cols[COL_R15S])
        if r1m < rqueue_softmax and r15s < rqueue_softmax:
            return cols[COL_HOST]
        elif r1m >= RQUEUE_HARDMAX or r15s >= RQUEUE_HARDMAX:
            print >>sys.stderr, "INFO polyrcp try #%d; r1m=%s; r15s=%s; hard max=%s; retrying in %d s" % (index, cols[COL_R1M], cols[COL_R15S], RQUEUE_HARDMAX, HARD_SLEEP_TIME)
            time.sleep(HARD_SLEEP_TIME)
        else:
            rqueue_softmax = min(rqueue_softmax+RQUEUE_SOFTMAX_STEP, RQUEUE_HARDMAX)
            print >>sys.stderr, "INFO polyrcp try #%d; r1m=%s; r15s=%s; soft max=%s; retrying in %d s" % (index, cols[COL_R1M], cols[COL_R15S], rqueue_softmax, SOFT_SLEEP_TIME)
            time.sleep(SOFT_SLEEP_TIME)

def node_spec(filename, hostname, envname):
    if filename.startswith(hostname + ":"):
        return get_node(os.environ[envname]) + filename[len(hostname):]
    else:
        return filename

def replace_host(filename):
    filename = node_spec(filename, "ecs2", "ECS2_NODES")
    filename = node_spec(filename, "ecs4", "ECS4_NODES")
    return filename

def copy(filename0, filename1):
    filename0, filename1 = map(replace_host, (filename0, filename1))
    lsrcp_cmdline = " ".join([LSRCP_CMD, filename0, filename1])
    print lsrcp_cmdline

    oldpath = os.environ["PATH"]
    try:
        os.environ["PATH"] = "" # no rcp!
        os.system(lsrcp_cmdline)
    finally:
        os.environ["PATH"] = oldpath
    
def main(args):
    copy(*args)

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
