#!/usr/bin/env python

import sys
import json
import ethtool
import shlex
import re

def match_list(value, list):
    if len(list) == 0:
        return False

    for exp in list:
        if re.match(exp, value):
            return True

    return False

def has_match(name, module_type, bus_type, name_list, module_type_list, bus_type_list):
    return match_list(name, name_list) or \
                    match_list(module_type, module_type_list) or match_list(bus_type, bus_type_list)

# read the argument string from the arguments file
args_file = sys.argv[1]
args_data = file(args_file).read()

exclude_names=[]
exclude_module_types=[]
exclude_bus_types=[]
include_names=[]
include_module_types=[]
include_bus_types=[]
ignore_names=[]
ignore_module_types=["tun", "bridge", "bonding", "veth"]
ignore_bus_types=["^\W*$", "N/A", "tap"]
debug_out = False

# parse the task options
arguments = shlex.split(args_data)
for arg in arguments:
    # exclude any arguments without an equals in it
    if "=" in arg:
        (key, value) = arg.split("=")

    if key == "exclude-names":
        exclude_names = re.split("\W*,\W*", value)
    elif key == "exclude-module-types":
        exclude_module_types = re.split("\W*,\W*", value)
    elif key == "exclude-bus-types":
        exclude_bus_types = re.split("\W*,\W*", value)
    elif key == "include-names":
        include_names = re.split("\W*,\W*", value)
    elif key == "include-module-types":
        include_module_types = re.split("\W*,\W*", value)
    elif key == "include-bus-types":
        include_bus_types = re.split("\W*,\W*", value)
    elif key == "ignore-names":
        ignore_names = re.split("\W*,\W*", value)
    elif key == "ignore-module-types":
        ignore_module_types = re.split("\W*,\W*", value)
    elif key == "ignore-bus-types":
        ignore_bus_types = re.split("\W*,\W*", value)
    elif key == "debug":
        debug_out = value.lower() in ["true", "yes", "on", "t", "y", "1"]
    elif key[0] != '_':
        raise ValueError('Unknown option to task "%s"' % key)

included = {}
ignored = {}
excluded = {}
debug = []

if debug_out:
    debug.append("EXCLUDES: '%s', '%s', '%s'" % (exclude_names, exclude_module_types, exclude_bus_types))
    debug.append("INCLUDE: '%s', '%s', '%s'" % (include_names, include_module_types, include_bus_types))
    debug.append("IGNORE: '%s', '%s', '%s'" % (ignore_names, ignore_module_types, ignore_bus_types))

for i in ethtool.get_devices():
    o = { "name": i }
    try:
        module = ethtool.get_module(i)
        businfo = ethtool.get_businfo(i)

        # If it matches an ignore pattern then just ignore it.
        if has_match(i, module, businfo, ignore_names, ignore_module_types, ignore_bus_types):
            if debug_out: debug.append("IGNORE '%s' on ignore match" % i)
            ignored[i] = {
                "name": i,
                "module": module,
            }
            continue

        # If no include specifications have been set and the interface is not ignored
        # it needs to be considered for inclusion
        if len(include_names) + len(include_module_types) + len(include_bus_types) == 0:
            # If it matches exclude list then exclude it, else include it
            if has_match(i, module, businfo, exclude_names, exclude_module_types, exclude_bus_types):
                if debug_out: debug.append("EXCLUDE '%s' with no include specifiers, but with exclude match" %i)
                excluded[i] = {
                    "name": i,
                    "module": module,
                }
                continue
            if debug_out: debug.append("INCLUDE '%s' with no include specifiers, but with no exclude match" % i)
            included[i] = {
                "name": i,
                "module": module,
            }
            continue

        # If any of the include specifications are set then the interface must match at least one
        # to be added to the mached list.
        if has_match(i, module, businfo, include_names, include_module_types, include_bus_types):
            if debug_out: debug.append("MATCH '%s' has include match" % i)
            # If it matches exclude list then exclude it, else include it
            if has_match(i, module, businfo, exclude_names, exclude_module_types, exclude_bus_types):
                if debug_out: debug.append("EXCLUDE '%s' with include match, but also with exclude match" % i)
                excluded[i] = {
                    "name": i,
                    "module": module,
                }
                continue
            if debug_out: debug.append("INCLUDE '%s' with include match and with no exclude match" % i)
            included[i] = {
                "name": i,
                "module" : module,
            }
            continue

        # Implicitly ignore
        if debug_out: debug.append("IGNORE: '%s' implicitly" %i)
        ignored[i] = {
            "name": i,
            "module": module,
        }

    except:
        pass

result = {
    "changed" : False,
    "ansible_facts" : {
        "netinfo" : {
            "included" : included,
            "excluded" : excluded,
            "ignored"  : ignored,
        },
    },
}

if debug_out: result["ansible_facts"]["netinfo"]["debug"] = debug

print json.dumps(result)
