#! /usr/bin/python -u
# Copyright 2012 Cumulus Networks LLC, all rights reserved

import subprocess
import getopt
import sys
import os.path
import re
import syslog

import snmp_passpersist as snmp

debug = 0
already_logged = False
oid_base = '.1.3.6.1.2.1.31.1.1.1.18'

def pp_add_str(oid, val):
    if debug:
        print '%s : %s' %(oid, val)
    else:
        pp.add_str(oid, val)

def update ():
    """ This function gets description of an interface from:
    - 'ip link' alias field if present
    or
    - description in zebra.conf
        or
    - sets interface description = interface name

    Assumes ip -o link output looks like the below:
    "54: swp52: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 500\    link/ether 00:e0:ec:27:52:a8 brd ff:ff:ff:ff:ff:ff\    alias 40G interface"

    And zebra.conf interface description looks like the below:
    interface swp3
    description "40G interface"
    """
    global already_logged
    if_zebra_descr_list = {}  # interface descriptions from zebra.conf`
    if_dict = {}              # interface dictionary for ip link output
                              # - keys: interface number from ip output
                              # - values: { name : '', alias : '' }


    # Get interface descriptions from zebra.conf
    try:
        f = open ("/etc/quagga/zebra.conf", "r");
        file_open = True;
    except IOError as e:
        file_open = False;

    matchstr = "\s*interface\s*"
    ifname = ''
    if file_open == True:
        for line in f:
            if ("description" in line and line[0] != '!' and line[0] != '#' and ifname != ''):
                if_zebra_descr_list[ifname] = line.replace("description", '').strip()
            if (re.match (matchstr, line) != None):
                ifname = line.split()[1]


    # Get interface descriptions from ip -o link show output
    try:
        ip_lines = subprocess.check_output((['/bin/ip', '-o', 'link', 'show']),
                                           stderr=subprocess.STDOUT,
                                           shell=False).splitlines()
    except Exception as e:
        ip_lines = []
        if not already_logged:
            already_logged = True
            syslog.syslog('snmpifAlias_pp: Exception=%s' % e)

    for line in ip_lines:
        ifnum = int(line.split(':')[0].strip())
        ifname = line.split(':')[1].strip()
        if_dict[ifnum] = { 'name': ifname, 'alias': '' }
        if 'alias' in line:
            if_dict[ifnum]["alias"] = line[line.index('alias')+6:].strip()

    for ifnum in sorted(if_dict.keys()):
        oid = "%d"%ifnum
        ifname = if_dict[ifnum]["name"]  
        ifalias = if_dict[ifnum]["alias"]
        if ifalias != '':
            pp_add_str(oid, ifalias)
        else:
            if ifname in if_zebra_descr_list.keys():
               pp_add_str(oid, if_zebra_descr_list[ifname])
            else:
               pp_add_str(oid, ifname)


if debug:
    update()
else:
    pp = snmp.PassPersist(oid_base)
    pp.start(update, 30)

