#!/usr/bin/env python
import sys
from sys import exit
import argparse
import requests
import json
import time
import re

OK   = 0
WARN = 1
CRIT = 2
UNKN = 3

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-w', '--warn', dest='warn', type=int, default=90, help='warn level')
    parser.add_argument('-c', '--crit', dest='crit', type=int, default=95, help='crit level')
    parser.add_argument('-m', '--mins', dest='mins', type=int, default=5,  help='mins to average')
    parser.add_argument('-n', '--nics', dest='nics', type=int, default=2,  help='number of nics')
    parser.add_argument('-H', '--host', dest='host', help='hostname', required=True)
    args = parser.parse_args()

    match = re.match(r'^(?P<pop>[a-zA-Z]+[0-9]+-)?(?P<cluster>[a-zA-Z]+)\d+', args.host)
    if match:
        pop     = match.group('pop') or "sfo01"
        cluster = match.group('cluster')
    else:
        print "Error: Couldnt process hostname: '%s'" % args.host
        exit(UNKN)

    metric  = "bytes_out"

    try:
        r = requests.get(
                "https://ganglia-api.internal.justin.tv/graph.php?r=hour&c=%s&h=%s.justin.tv&m=%s&jr=&js=&json=0"
                % (cluster, args.host, metric))
    except Exception as e:
        print "UNKN: Exception '%s'" % e
        exit(UNKN)


    if r.ok:
        data = json.loads(r.text)

        if not data:
            print "Error: Can't get data for host '%s'." % args.host
            exit(UNKN)

        datapoints = data[0]["datapoints"] or []

        # Measure 5 minutes from the last valid datapoint
        now = int(time.time())
        last_timestamp = now
        for (value, data_time) in reversed(datapoints):
            if value != 0:
                last_timestamp = data_time
                break


        sum = 0
        count = 0
        for (value, data_time) in datapoints:
            if data_time > (last_timestamp - (60 * args.mins)):
                if value == 0:
                    continue

                count += 1
                sum   += value

        if count != 0:
            average = sum / count
        else:
            average = 0

        max_level = args.nics * 1000
        crit_level = (args.crit / 100.0) * max_level
        warn_level = (args.warn / 100.0) * max_level
        mbps = (average / 1000 / 1000) * 8

        format = "%s: %0.2f mbps (%.2f%% / %d interfaces) | %s" 
        format2 = "(warn: %.0f%% / crit: %.0f%%)" % ((args.warn), (args.crit))
        if mbps < 0:
            print format % ("UNKN", mbps, (mbps / max_level) * 100, args.nics, format2)
            exit(UNKN)
        elif mbps > crit_level:
            print format % ("CRIT", mbps, (mbps / max_level) * 100, args.nics, format2)
            exit(CRIT)
        elif mbps > warn_level:
            print format % ("WARN", mbps, (mbps / max_level) * 100, args.nics, format2)
            exit(WARN)
        else:
            print format % ("OK", mbps, (mbps / max_level) * 100, args.nics, format2)
            exit(OK) 
    else:
        print >> sys.stderr, "Error [%d]: %s" % (r.status_code, r.reason)
        return UNKN

if __name__ == "__main__":
    sys.exit(main())
