#!/usr/bin/env python

"""A simple requests per second (rps) counter."""

import os
import sys
import time
import fcntl
import getopt
import select


SEP = '\n'


def usage():
    """Usage message"""

    print "USAGE: tail -f access_log | rpstool"


def parse_args():
    """Args parser"""

    try:
        opts = getopt.getopt(sys.argv[1:], "h", ["help"])[0]
    except getopt.GetoptError as err:
        print str(err)
        usage()
        sys.exit(-1)
    for opt in opts:
        if opt[0] in ("-h", "--help"):
            usage()
            sys.exit()


def prepare_stdin():
    """Makes stdin non-blocking"""

    try:
        fcntl.fcntl(sys.stdin, fcntl.F_SETFL, os.O_NONBLOCK)
    except IOError:
        print "SORRY, could not make stdin non-blocking"
        sys.exit(-2)


def main():
    """Parsing args & processing stdin"""

    parse_args()
    prepare_stdin()
    buf = ""
    total_reqs = 0

    print "Use Ctrl + C to terminate the program"
    # running forever until Ctrl + C is caught
    while True:
        time_left, cnt = 1.0, 0
        while time_left >= 0:
            time_start = time.time()
            # waiting for event or timeout
            try:
                rlist = select.select([sys.stdin], [], [], time_left)[0]
            except KeyboardInterrupt:
                print "BYE, %d total reqs" % total_reqs
                sys.exit(0)
            # timeout
            if not rlist:
                break
            time_left -= (time.time() - time_start)
            buf += sys.stdin.read()
            try:
                ridx = buf.rindex(SEP)
            except ValueError:
                continue
            # counting the number of seps (=number of reqs processed)
            idx = 0
            while True:
                idx = buf.find(SEP, idx, ridx)
                if idx == -1:
                    break
                cnt += 1
                idx += 1
            cnt += 1
            buf = buf[ridx + 1:]
        print("%d rps" % cnt)
        total_reqs += cnt


if __name__ == "__main__":
    main()
