#!/usr/bin/env python

# Copyright (C) 2014  Sangoma Technologies Corp.
# All Rights Reserved.
#
# Author(s):
# Leonardo Lang <lang@sangoma.com>
#
# This code is Sangoma Technologies Confidential Property.
# Use of and access to this code is covered by a previously executed
# non-disclosure agreement between Sangoma Technologies and the Recipient.
# This code is being supplied for evaluation purposes only and is not to be
# used for any other purpose.

import os
import re
import sys
import logging
import optparse
import subprocess

PROGNAME = os.path.basename(os.path.abspath(sys.argv[0]))

def setup_logger(progname, debugmode):
    logger = logging.getLogger(progname)

    if debugmode is None:
        logger.setLevel(logging.INFO)
        formatter = logging.Formatter('%(message)s')
    else:
        logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(name)s: %(levelname)s %(message)s')

    out_handler = logging.StreamHandler()
    out_handler.setFormatter(formatter)
    logger.addHandler(out_handler)
    return logger

FOUND_MESSAGE = 'Found matching device: '
NOT_FOUND_MESSAGE = 'No devices found!'

parser = optparse.OptionParser(usage='%(name)s [options] <vendor:device> [vendor:device..] ...'.format(name=PROGNAME))

parser.add_option('', '--debug',   action='store_true', help='Enable debug messages.')

parser.add_option('', '--found-msg',     dest='found_msg',    default=FOUND_MESSAGE,     help='Default found message ({msg}).'.format(msg=FOUND_MESSAGE))
parser.add_option('', '--not-found-msg', dest='notfound_msg', default=NOT_FOUND_MESSAGE, help='Default not found message ({msg}).'.format(msg=NOT_FOUND_MESSAGE))

(options, args) = parser.parse_args()

logger = setup_logger(PROGNAME, options.debug)

blacklist = []

for arg in args:
    item = {}
    try:
        item['vendor'], item['device'] = arg.split(':')
        blacklist.append(item)
    except:
        logger.debug('invalid format for argument "{arg}", ignoring..'.format(arg=arg))

if len(blacklist) == 0:
    logger.error('device list is empty, exiting')
    sys.exit(2)

EXP_QUOTE = '"([^"]*)\\[([^\\]]+)\\]"'
EXP_MAYBE = '"(([^"]*)\\[([^\\]]+)\\])?"'

RE_FILTER = re.compile('(^[0-9a-f:.]+) {a} {b} {c} (-[a-z0-9]+ )+{d} {e}'.format(a=EXP_QUOTE, b=EXP_QUOTE, c=EXP_QUOTE, d=EXP_MAYBE, e=EXP_MAYBE))

proc = subprocess.Popen(['lspci', '-nn', '-mm'], stdout=subprocess.PIPE)
pout, _ = proc.communicate()

for line in pout.splitlines():
    m = RE_FILTER.match(line)

    if m is None:
        logger.debug('line not matched format: {line}'.format(line=line.strip()))
        continue

    logger.debug('checking line: {line}'.format(line=line.strip()))

    for item in blacklist:
        matched = False
        v = item.get('vendor')
        if v is not None:
            if v != m.group(5):
                continue
            matched = True
        v = item.get('device')
        if v is not None:
            if v != m.group(7):
                continue
            matched = True
        if matched:
            if options.found_msg != '':
                logger.info('{msg}{name}'.format(msg=options.found_msg, name=m.group(6)))
            sys.exit(0)

if options.notfound_msg != '':
    logger.info(options.notfound_msg)

sys.exit(1)
