import re
import sys
import subprocess
import json


def shell(command):
    _ps = subprocess.Popen(
        command.split(),
        stdout=subprocess.PIPE
    ).communicate()[0].decode()

    return _ps


def cut_option(_param, _options_list, _option="n/a"):
    _result_list = []
    if _param in _options_list:
        _index = _options_list.index(_param)
        _option = _options_list[_index+1]
        _l1 = _options_list[:_index]
        _l2 = _options_list[_index+2:]
        _result_list = _l1 + _l2
    else:
        _result_list = _options_list
    return _option, _result_list


def get_linked_devices(if_name):
    if '@' in if_name:
        _name = if_name[:if_name.index('@')]
    else:
        _name = if_name
    # identify device type
    _dev_link_path = shell('readlink /sys/class/net/{}'.format(_name))
    _type = "unknown"
    if len(_dev_link_path) > 0:
        _tmp = _dev_link_path.split('/')
        _tmp = _tmp[_tmp.index("devices") + 1]
        if _tmp.startswith("pci"):
            _type = "physical"
        elif _tmp.startswith("virtual"):
            _type = "virtual"

    # get linked devices if any
    _links = shell(
        "find /sys/class/net/{}/ -type l".format(_name)
    )
    # there can be only one parent device
    _lower = None
    # can be more than one child device
    _upper = None
    for line in _links.splitlines():
        _line = line.rsplit('/', 1)[1]
        if _line.startswith("upper_"):
            if not _upper:
                _upper = []
            _upper.append(_line[6:])
        elif _line.startswith("lower_"):
            if not _lower:
                _lower = []
            _lower.append(_line[6:])

    return _lower, _upper, _type


def get_ifs_data():
    # Collect interface and IPs data
    # Compile regexps for detecting IPs
    if_start = re.compile("^[0-9]+: .*: \<.*\> .*$")
    if_link = re.compile("^\s{4}link\/ether\ .*$")
    if_ipv4 = re.compile("^\s{4}inet\ .*$")
    # variable prototypes
    _ifs = {}
    _if_name = None
    # get the "ip a" output
    _ifs_raw = shell('ip a')
    for line in _ifs_raw.splitlines():
        _if_data = {}
        if if_start.match(line):
            _tmp = line.split(':')
            _if_name = _tmp[1].strip()
            _if_options = _tmp[2].strip().split(' ')
            _lower, _upper, _type = get_linked_devices(_if_name)
            _if_data['order'] = _tmp[0]
            _if_data['mtu'], _if_options = cut_option("mtu", _if_options)
            _if_data['qlen'], _if_options = cut_option("qlen", _if_options)
            _if_data['state'], _if_options = cut_option("state", _if_options)
            _if_data['other'] = _if_options
            _if_data['ipv4'] = {}
            _if_data['mac'] = {}
            _if_data['type'] = _type
            _if_data['upper'] = _upper
            _if_data['lower'] = _lower
            _ifs[_if_name] = _if_data
        elif if_link.match(line):
            if _if_name is None:
                continue
            else:
                _tmp = line.strip().split(' ', 2)
                _mac_addr = _tmp[1]
                _options = _tmp[2].split(' ')
                _brd, _options = cut_option("brd", _options)
                _ifs[_if_name]['mac'][_mac_addr] = {}
                _ifs[_if_name]['mac'][_mac_addr]['brd'] = _brd
                _ifs[_if_name]['mac'][_mac_addr]['other'] = _options
        elif if_ipv4.match(line):
            if _if_name is None:
                continue
            else:
                _tmp = line.strip().split(' ', 2)
                _ip = _tmp[1]
                _options = _tmp[2].split(' ')
                _brd, _options = cut_option("brd", _options)
                # TODO: Parse other options, mask, brd, etc...
                _ifs[_if_name]['ipv4'][_ip] = {}
                _ifs[_if_name]['ipv4'][_ip]['brd'] = _brd
                _ifs[_if_name]['ipv4'][_ip]['other'] = _options
    
    # Collect routes data and try to match it with network
    # Compile regexp for detecting default route
    _routes = {
        'raw': []
    }
    _ip_route_raw = shell("ip -4 r")
    for line in _ip_route_raw.splitlines():
        _o = line.strip().split(' ')
        if line.startswith("default"):
            # default gateway found, prepare options and cut word 'default'
            _gate, _o = cut_option('via', _o, _option="0.0.0.0")
            _dev, _o = cut_option('dev', _o)
            _routes[_o[0]] = {
                'gateway': _gate,
                'device': _dev,
                'args': " ".join(_o[1:])
            }
        else:
            # network specific gateway found
            _gate, _o = cut_option('via', _o, _option=None)
            _dev, _o = cut_option('dev', _o)
            _src, _o = cut_option('src', _o)
            _routes[_o[0]] = {
                'gateway': _gate,
                'device': _dev,
                'source': _src,
                'args': " ".join(_o[1:])
            }

    _ifs["routes"] = _routes
    return _ifs


ifs_data = get_ifs_data()

if len(sys.argv) > 1 and sys.argv[1] == 'json':
    sys.stdout.write(json.dumps(ifs_data))
else:
    _ifs = sorted(ifs_data.keys())
    _ifs.remove("lo")
    _ifs.remove("routes")
    for _idx in range(len(_ifs)):
        _linked = ""
        if ifs_data[_ifs[_idx]]['lower']:
            _linked += "lower:{} ".format(
                ','.join(ifs_data[_ifs[_idx]]['lower'])
            )
        if ifs_data[_ifs[_idx]]['upper']:
            _linked += "upper:{} ".format(
                ','.join(ifs_data[_ifs[_idx]]['upper'])
            )
        _linked = _linked.strip()
        print("{0:8} {1:30} {2:18} {3:19} {4:5} {5:4} {6}".format(
            ifs_data[_ifs[_idx]]['type'],
            _ifs[_idx],
            ",".join(ifs_data[_ifs[_idx]]['mac'].keys()),
            ",".join(ifs_data[_ifs[_idx]]['ipv4'].keys()),
            ifs_data[_ifs[_idx]]['mtu'],
            ifs_data[_ifs[_idx]]['state'],
            _linked
        ))

    print("\n")
    # default route
    print("default via {} on {} ({})".format(
        ifs_data["routes"]["default"]["gateway"],
        ifs_data["routes"]["default"]["device"],
        ifs_data["routes"]["default"]["args"]
    ))
    # detected routes
    _routes = ifs_data["routes"].keys()
    _routes.remove("raw")
    _routes.remove("default")
    _rt = ifs_data["routes"]
    for idx in range(0, len(_routes)):
        if _rt[_routes[idx]]["gateway"]:
            print("{0:18} <- {1:16} -> {2:18} on {3:30} ({4})".format(
                _routes[idx],
                _rt[_routes[idx]]["gateway"],
                _rt[_routes[idx]]["source"],
                _rt[_routes[idx]]["device"],
                _rt[_routes[idx]]["args"]
            ))
        else:
            print("{0:18} <- -> {1:18} on {2:30} ({3})".format(
                _routes[idx],
                _rt[_routes[idx]]["source"],
                _rt[_routes[idx]]["device"],
                _rt[_routes[idx]]["args"]
            ))
