#!/usr/bin/env python

"""The clang static analyzer results viewer.
"""

import sys
import posixpath
import thread
import time
import urllib
import webbrowser

# How long to wait for server to start.
kSleepTimeout = .05
kMaxSleeps = int(60 / kSleepTimeout)

# Default server parameters

kDefaultHost = '127.0.0.1'
kDefaultPort = 8181
kMaxPortsToTry = 100

###

def url_is_up(url):
    try:
        o = urllib.urlopen(url)
    except IOError:
        return False
    o.close()
    return True

def start_browser(port, options):
    import urllib, webbrowser

    url = 'http://%s:%d'%(options.host, port)
    
    # Wait for server to start...
    if options.debug:
        sys.stderr.write('%s: Waiting for server.' % sys.argv[0])
        sys.stderr.flush()
    for i in range(kMaxSleeps):
        if url_is_up(url):
            break
        if options.debug:
            sys.stderr.write('.')
            sys.stderr.flush()
        time.sleep(kSleepTimeout)
    else:
        print >>sys.stderr,'WARNING: Unable to detect that server started.'

    if options.debug:
        print >>sys.stderr,'%s: Starting webbrowser...' % sys.argv[0]
    webbrowser.open(url)

def run(port, options, root):
    import ScanView
    try:
        print 'Starting scan-view at: http://%s:%d'%(options.host,
                                                     port)
        print '  Use Ctrl-C to exit.'
        httpd = ScanView.create_server((options.host, port),
                                       options, root)
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass

def port_is_open(port):
    import SocketServer
    try:
        t = SocketServer.TCPServer((kDefaultHost,port),None)
    except:
        return False
    t.server_close()
    return True

def main():    
    from optparse import OptionParser
    parser = OptionParser('usage: %prog [options] <results directory>')
    parser.set_description(__doc__)
    parser.add_option(
        '--host', dest="host", default=kDefaultHost, type="string",
        help="Host interface to listen on. (default=%s)" % kDefaultHost)
    parser.add_option(
        '--port', dest="port", default=None, type="int",
        help="Port to listen on. (default=%s)" % kDefaultPort)
    parser.add_option("--debug", dest="debug", default=0, 
                      action="count",
                      help="Print additional debugging information.")
    parser.add_option("--auto-reload", dest="autoReload", default=False, 
                      action="store_true",
                      help="Automatically update module for each request.")
    parser.add_option("--no-browser", dest="startBrowser", default=True, 
                      action="store_false",
                      help="Don't open a webbrowser on startup.")
    parser.add_option("--allow-all-hosts", dest="onlyServeLocal", default=True, 
                      action="store_false",
                      help='Allow connections from any host (access restricted to "127.0.0.1" by default)')
    (options, args) = parser.parse_args()

    if len(args) != 1:
        parser.error('No results directory specified.')
    root, = args

    # Make sure this directory is in a reasonable state to view.
    if not posixpath.exists(posixpath.join(root,'index.html')):
        parser.error('Invalid directory, analysis results not found!')

    # Find an open port. We aren't particularly worried about race
    # conditions here. Note that if the user specified a port we only
    # use that one.
    if options.port is not None:
        port = options.port
    else:    
        for i in range(kMaxPortsToTry):
            if port_is_open(kDefaultPort + i):
                port = kDefaultPort + i
                break
        else:
            parser.error('Unable to find usable port in [%d,%d)'%(kDefaultPort,
                                                                  kDefaultPort+kMaxPortsToTry))

    # Kick off thread to wait for server and start web browser, if
    # requested.
    if options.startBrowser:
        t = thread.start_new_thread(start_browser, (port,options))

    run(port, options, root)

if __name__ == '__main__':
    main()
