#! /usr/bin/python
'''A tool to display MAC addresses for network interfaces'''

import re
import sys
import getopt

import isi.app.lib.procs as procs

COMMA = ','
SPACE = ' '
SEMICOLON = ';'

#----------------------------------------------------------------------
def getInterfaceNames(iType=None):
    names = []
    # Ignore the loopback interface (lo0) since it doesn't have a MAC
    if iType is not None:
        # Filter by type
        cmd = 'ifconfig | grep -v LOOPBACK | grep flags | grep %s' % iType
    else:
        # All interfaces
        cmd = 'ifconfig | grep -v LOOPBACK | grep flags'

    (error, output) = procs.get_cmd_output(cmd)
    if error:
        print 'ERROR: ifconfig failed'
        for line in output:
            print line
    else:
        for line in output:
            m = re.match('^(?P<value>\w+)', line)
            if m:
                names.append(m.group('value'))

    return names

#----------------------------------------------------------------------
def getMacOfInterface(name):
    macAddr = None
    # Ignore the loopback interface (lo0) since it doesn't have a MAC
    cmd = 'ifconfig %s | grep -v LOOPBACK | grep -e "ether" -e "lladdr"' % name
    (error, output) = procs.get_cmd_output(cmd)
    if error:
        print 'ERROR: ifconfig failed for "%s"' % name
        for line in output:
            print line
    else:
        for line in output:
            m = re.match('^.*ether (?P<value>\w+.*$)', line)
            if m:
                macAddr = m.group('value')
            else:
                m = re.match('^.*lladdr (?P<value>\w+.*$)', line)
                if m:
                    macAddr = m.group('value')

    return macAddr

#----------------------------------------------------------------------
def usage():
    usage = (
'''Usage: %s [OPTION] [ARG]

OPTIONS:
    -h, --help  Prints this text
    --flat      Print flat mode (all on one line)

ARGS:
    --name      Single interface name (i.e. em0, igb0, cxgb1, ix0, ib0) or 
                quoted, comma separated list of names (i.e. 'em0, ib1')
                    NOTE: Omitting this argument will show all interfaces

    --type      Interface type (i.e. em, igb, ib, cxgb, ix)
''')

    print usage % (sys.argv[0])

#----------------------------------------------------------------------
def main(argv):
    names = []
    flat = False
    nameString = None
    typeString = None

    try:
        opt, args = getopt.getopt(argv, 'h', ['help', 'flat', 'name=', 'type='])

    except getopt.GetoptError, err:
        print str(err)
        usage()
        sys.exit(1)

    if opt and len(opt) == 0 and args and len(args) == 0:
        usage()
        sys.exit(1)

    for o, a in opt:
        if o in ('-h', '--help'):
            usage()
            sys.exit(0)
        elif o in ('--flat'):
            flat = True
        elif o in ('--name'):
            nameString = str(a)
        elif o in ('--type'):
            typeString = str(a)

    # Sanity check user input -- If neither name nor type was specified,
    # default to all interfaces. If both name and type was specified, 
    # that's just silly... 
    if nameString is None and typeString is None:
        nameString = 'all'
    elif nameString is not None and typeString is not None:
        print 'Specify name or type but not both'
        usage()
        sys.exit(1)

    # Strip any spaces that might be in the list of names
    if nameString is not None:
        nameString.strip(SPACE)

    # Generate list of interface names
    if typeString is not None:
        names = getInterfaceNames(typeString)
    elif nameString == 'all':
        names = getInterfaceNames()
    elif nameString is not None and nameString.find(COMMA):
        names = nameString.split(COMMA)
    else:
        names.append(nameString)

    if flat:
        first = True
        print 'Interfaces ',
        for name in names:
            if not first:
                sys.stdout.write(COMMA + SPACE)
            sys.stdout.write(name)
            if first:
                first = False

        print  SEMICOLON,
        print 'MACs=',

    first = True
    for name in names:
        macAddr = getMacOfInterface(name)
        if flat:
            if not first:
                sys.stdout.write(COMMA + SPACE)
            sys.stdout.write(macAddr)
        else:
            print 'Interface %s%s MAC=%s' % (name, SEMICOLON, macAddr)
        if first:
            first = False
    if flat:
        sys.stdout.write('\n')

    sys.exit(0)

#----------------------------------------------------------------------
if __name__ == '__main__':
    main(sys.argv[1:])
