"""
simpleSnapRouter.py - an example for the SNAP Connect User Manual

By default, enables listening for incoming TCP/IP connections.

Command line options allow:

1) NOT listening for incoming TCP/IP connections
2) Establishing a serial connection on a "COM" port
3) Establishing a serial connection on a legacy USB device like a Synapse SN163 or SN132
4) Establishing a serial connection on a USB device like a SS200
5) Connecting to other SNAP Connect instances over TCP/IP
6) Changing the user, and password settings from their default value of "public"
"""
import logging
from optparse import OptionParser
from snapconnect import snap

DEFAULT_USER = 'public'
DEFAULT_PASSWORD = 'public'

my_user = DEFAULT_USER
my_password = DEFAULT_PASSWORD

def my_client_auth(realm):
    """
    An example client authorization function

    Returns the previously set username and password to the remote server
    to use as it's authorization, *if* the specified realm is correct

    realm : The realm specified by the remote server. Note that this is
    intended for future expansion. Currently it is always 'SNAPcom'.
    """
    return (my_user, my_password)

def my_server_auth(realm, username):
    """
    An example server authentication function

    Returns the password for the specified username in the realm

    realm : This server's realm (currently unused, future expansion)
    username : The username specified by the remote server
    """
    if username == my_user:
        return my_password

def echo(obj):
    """Just a function that can be called remotely"""
    print str(obj)

def main():
    global comm
    global my_user, my_password

    usage = "usage: %prog [options] [other-node-IP-addresses]"
    parser = OptionParser(usage)

    parser.add_option("-d", "--deaf", action="store_true", dest="no_listener", default=False, help="DON'T listen for incoming TCP/IP connections (default is DO listen)")

    parser.add_option("-c", "--com", dest="comport", help="open a connection on the specified COM port (0 = COM1)")
    parser.add_option("-s", "--ss200", dest="ss200", help="open a connection on the specified SS200 device (0 = SNAPstick0)")
    parser.add_option("-l", "--legacy", dest="usb", help="open a connection on the specified USB device (0 = USB0)")

    parser.add_option("-u", "--user", dest="user", default=DEFAULT_USER, help='specify an alternative SNAP Realm user name(default is "public")')
    parser.add_option("-p", "--password", dest="password", default=DEFAULT_PASSWORD, help='specify an alternative SNAP Realm password (default is "public")')

    (options, args) = parser.parse_args()

    print options
    print args
    
    funcdir = {"echo": echo}
    comm = snap.Snap(funcs=funcdir)

    my_user = options.user
    my_password = options.password
    
    if options.no_listener:
        print "Listening for incoming TCP/IP connections has been disallowed by user"
    else:
        print "Listening for incoming TCP/IP connections"
        comm.accept_tcp(auth_info=my_server_auth)

    if len(args) != 0:
        # Establish requested outbound TCP/IP connections
        for arg in args:
            print "Establishing a TCP/IP link to "+arg
            comm.connect_tcp(arg, auth_info=my_client_auth)

    # Did the user ask us to open a normal serial port connection (COM1-COMn)?
    if options.comport != None:
        port = int(options.comport)
        print "Opening a serial connection on COM%d" % (port+1)
        try:
            comm.open_serial(snap.SERIAL_TYPE_RS232, port)
        except Exception, e:
            print "Invalid COM port specified"
        
    # Did the user ask us to open a connection to a SS200?
    if options.ss200 != None:
        port = int(options.ss200)
        print "Opening a serial connection to SNAPstick%d" % (port)
        try:
            comm.open_serial(snap.SERIAL_TYPE_SNAPSTICK200, port)
        except Exception, e:
            print "Invalid SS200 device specified"
        
    # Did the user ask us to open a connection to a legacy Synapse USB device?
    if options.usb != None:
        port = int(options.usb)
        print "Opening a serial connection on USB%d" % (port)
        try:
            comm.open_serial(snap.SERIAL_TYPE_SNAPSTICK100, port)
        except Exception, e:
            print "Invalid USB port specified"
        
    comm.loop()        
        
if __name__ == '__main__':
    logging.basicConfig(filename='simpleSnapRouter.log', level=logging.DEBUG, format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
    main()
