#!/usr/bin/env python
# -*- coding: ascii -*-

'''Implementation of a mediaproxy request dispatcher for SER.

 The dispatcher implements an architecture where SER will work with multiple
MediaProxy servers, be they local or remote. This can allow both using different
MediaProxy servers for different domains as well as distributing the traffic load on
multiple MediaProxy servers (running on multiple hosts or multiple MediaProxy
processes running on a multi-CPU machine).
 This dispatcher uses dns SRV records to decide where a request should be forwarded.
The dispatcher receives requests from SER's mediaproxy module and decides to which
local or remote MediaProxy to forward. If there are multiple dns SRV records for
a given domain, they will allow both load balancing of RTP traffic as well as
fallbacks in case one is not working.
 After finding the MediaProxy server that will handle the request, the
dispatcher will forward the request that came from SER's mediaproxy module to that
server, read back the answer and handle that answer to SER's mediaproxy module.

Copyright 2004-2005 Dan Pascu
'''

## add the modules subdir to the import search path
import sys, os
sys.path[1:1] = [os.path.realpath((os.path.dirname(sys.argv[0]) or '.') + '/modules')]
del os


if __name__ == '__main__':
    import sys
    import daemon
    from optparse import OptionParser
    from options import ExtendedOptions
    from configuration import getOption, Boolean
    from version import release
    
    ver = '%%prog %s' % release
    parser = OptionParser(option_class=ExtendedOptions, version=ver)
    parser.add_option("--no-fork", action="store_false", dest="fork", default=1,
                      help="run the process in the foreground")
    parser.add_option("--pid", dest="pidFile", default='/var/run/proxydispatcher.pid',
                      help="pid file (/var/run/proxydispatcher.pid)", 
                      metavar="FILE")
    parser.add_option("--log", dest="logFile", default=None,
                      help="log to this file too, along with syslog (None)",
                      metavar="FILE")
    (options, args) = parser.parse_args()

    if options.fork:
        try:
            d = daemon.Daemon('proxydispatcher', options.pidFile, logFile=options.logFile, useSyslog=1)
        except daemon.DaemonError, why:
            print >>sys.stderr, "Mediaproxy dispatcher error: %s. Exiting." % why
            sys.exit(1)

    ## We test for this after we fork because we want the message to go to syslog if we fork
    shouldStart = getOption('Dispatcher', 'start', True, otype=Boolean)
    if not shouldStart:
        print "disabled from configuration"
        sys.exit(0)
    
    ## Import the dispatcher only after we fork, as it loads the accounting module which
    ## creates network connections, an extra thread and registers an atexit function.
    ## All these should only exist in the child to avoid troubles when the parent exits.
    import dispatcher

    try:
        config = dispatcher.DispatcherConfig
        ## Show some info on startup about the current settings
        print "Listening for commands on local socket `%s'" % config.socket
        if config.listen is not None:
            print "Listening for mediaproxy media timeout requests on %s:%s" % config.listen
        plural = " is"
        defaultProxy = config.defaultProxy
        domainId = 'domain://'
        if defaultProxy is None:
            where = "disabled.\nDomains without mediaproxy SRV records will not be handled."
        elif isinstance(defaultProxy, tuple):
            where = "on `%s:%s'" % defaultProxy
        elif defaultProxy.startswith(domainId):
            where = "those defined by domain %s" % defaultProxy[len(domainId):]
            plural = "s are"
        else:
            where = "on `%s'" % defaultProxy
        print "Default mediaproxy server%s %s" % (plural, where)

        dispatcher.start()
    except dispatcher.DispatcherError, why:
        print >>sys.stderr, "Mediaproxy dispatcher error: %s." % why
    except KeyboardInterrupt:
        print >>sys.stderr, "Got keyboard interrupt. Exiting."
    except daemon.DaemonQuit, msg:
        print >>sys.stderr, msg
    ## Save the current session in a file to preserve them if we restart
    dispatcher.saveSessions() # use atexit instead? -Dan

