import re

import whatap.util.logging_util as logging_util

# Interface names are read from platform collectors (psutil per-nic counters on
# AIX/HP-UX) and then handed to command lines. A collector that returns a bogus
# name must not be able to turn that into shell syntax or a bogus metric, so the
# name is checked against what a real interface can look like before it is used.
#
# Real names on these platforms are short and alphanumeric with a few
# separators: lan0, lan0:1, en0, lo0, eth0.1.
_NIC_NAME_RE = re.compile(r'^[A-Za-z0-9][A-Za-z0-9._:-]{0,31}$')


def isValidNicName(name):
    if not name:
        return False
    try:
        return _NIC_NAME_RE.match(name) is not None
    except TypeError:
        return False


def filterNicCounters(counters):
    """Drop entries whose interface name cannot be a real one.

    SERVER-1987: the HP-UX psutil extension walked past the entries
    get_physical_stat() had filled and returned uninitialised heap bytes as an
    interface name. Those bytes reached 'ifconfig ' + name on a shell, where a
    stray '>' created a file in the agent working directory - and any other
    shell metacharacter would have run as root. Dropping unusable names here
    keeps a single collector defect from becoming command execution.
    """
    if not counters:
        return counters
    safe = {}
    for name, counter in counters.items():
        if not isValidNicName(name):
            logging_util.debug("[nic] drop invalid interface name : ", repr(name))
            continue
        safe[name] = counter
    return safe
