from os import listdir, path
from subprocess import Popen,PIPE
from re import findall as refindall
from re import search as research
import salt.utils
import socket, struct, fcntl
import logging

logger = logging.getLogger(__name__)
stream = logging.StreamHandler()
logger.addHandler(stream)

def get_ip(iface='ens2'):

    ''' Get ip address from an interface if applicable

    :param iface: Interface name. Type: str

    '''

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sockfd = sock.fileno()
    SIOCGIFADDR = 0x8915
    ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)

    try:
        res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
    except:
        logger.debug("No ip addresses assigned to %s" % iface)
        return None

    ip = struct.unpack('16sH2x4s8x', res)[2]
    return socket.inet_ntoa(ip)

def get_nics():

    ''' List nics '''

    nics = []
    nics_list = listdir('/sys/class/net/')
    for nic_name in nics_list:
        if research('(bond|ens|enp|eth|one|ten|fourty)[0-9]+|br.+', nic_name):

            # Interface should be in "up" state in order to get carrier status
            Popen("ip li set dev " + nic_name + " up", shell=True, stdout=PIPE)

            with open("/sys/class/net/" + nic_name + "/carrier", 'r') as f:
                try:
                    carrier = int(f.read())
                except:
                    carrier = 0

            bond = ""
            if path.isfile("/sys/class/net/" + nic_name + "/master/uevent"):
                with open("/sys/class/net/" + nic_name + "/master/uevent", 'r') as f:
                    for line in f:
                        sline = line.strip()
                        if 'INTERFACE=bond' in sline:
                            bond = sline.split('=')[1]
            if len(bond) == 0:
                with open("/sys/class/net/" + nic_name + "/address", 'r') as f:
                    macaddr = f.read().strip()
            else:
                with open("/proc/net/bonding/" + bond, 'r') as f:
                    line = f.readline()
                    if_struct = False
                    while line:
                        sline = line.strip()
                        if 'Slave Interface: ' + nic_name in sline and not if_struct:
                            if_struct = True
                        if 'Permanent HW addr: ' in sline and if_struct:
                            macaddr = sline.split()[3]
                            break
                        line = f.readline()

            with open("/sys/class/net/" + nic_name + "/mtu", 'r') as f:
                mtu = f.read()

            ip = str(get_ip(nic_name))

            nics.append([nic_name, ip, macaddr, carrier, mtu])

    return sorted(nics)

def get_ten_pci():

    ''' List ten nics pci addresses '''

    nics = []
    nics_list = listdir('/sys/class/net/')
    for nic_name in nics_list:
        if research('ten[0-9]+', nic_name):
            with open("/sys/class/net/" + nic_name + "/device/uevent", 'r') as f:
                for line in f:
                    sline = line.strip()
                    if "PCI_SLOT_NAME=" in sline:
                        nics.append([nic_name , sline.split("=")[1]])

    return sorted(nics)

def mesh_ping(mesh):

    ''' One to many ICMP check

    :param hosts: Target hosts. Type: list of ip addresses

    '''

    io = []
    minion_id = __salt__['config.get']('id')

    for host, hostobj in mesh:
        if host == minion_id:
            for mesh_net, addr, targets in hostobj:
                if addr in targets:
                    targets.remove(addr)
                for tgt in targets:
                    # This one will run in parallel with everyone else
                    worker = Popen("ping -c 1 -w 1 -W 1 " + str(tgt), \
                        shell=True, stdout=PIPE, stderr=PIPE)
                    ping_out = worker.communicate()[0]
                    if worker.returncode != 0:
                        io.append(mesh_net + ': ' + addr + ' -> ' + tgt + ': Failed')

    return io

def minion_list():

    ''' List registered minions '''

    return listdir('/etc/salt/pki/master/minions/')

def verify_addresses():

    ''' Verify addresses taken from pillars '''

    nodes = nodes_addresses()
    verifier = {}
    failed = []

    for node, nodeobj in nodes:
        for item in nodeobj:
            addr = item[1]
            if addr in verifier:
                failed.append([node,verifier[addr],addr])
            else:
                verifier[addr] = node

    if failed:
        logger.error("FAILED. Duplicates found")
        logger.error(failed)
        return False
    else:
        logger.setLevel(logging.INFO)
        logger.info(["PASSED"])
        return True

def nodes_addresses():

    ''' List servers addresses '''

    compound = 'linux:network:interface'
    out = __salt__['saltutil.cmd']( tgt='I@' + compound,
                                    tgt_type='compound',
                                    fun='pillar.get',
                                    arg=[compound],
                                    timeout=10
                                  ) or None

    servers = []
    for minion in minion_list():
        addresses = []
        if minion in out:
            ifaces = out[minion]['ret']
            for iface in ifaces:
                ifobj = ifaces[iface]
                if ifobj['enabled'] and 'address' in ifobj:
                    if 'mesh' in ifobj:
                        mesh = ifobj['mesh']
                    else:
                        mesh = 'default'
                    addresses.append([mesh, ifobj['address']])
            servers.append([minion,addresses])

    return servers

def get_mesh():

    ''' Build addresses mesh '''

    full_mesh = {}
    nodes = nodes_addresses()

    for node, nodeobj in nodes:
        for item in nodeobj:
            mesh = item[0]
            addr = item[1]
            if not mesh in full_mesh:
                full_mesh[mesh] = []
            full_mesh[mesh].append(addr)

    for node, nodeobj in nodes:
        for item in nodeobj:
            mesh = item[0]
            tgts = full_mesh[mesh]
            item.append(tgts)

    return nodes

def ping_check():

    ''' Ping addresses in a mesh '''

    mesh = get_mesh()
    out = __salt__['saltutil.cmd']( tgt='*',
                                    tgt_type='glob',
                                    fun='net_checks.mesh_ping',
                                    arg=[mesh],
                                    timeout=10
                                  ) or None

    failed = []

    if out:
        for minion in out:
            ret = out[minion]['ret']
            if ret:
                failed.append(ret)
    else:
        failed = ["No response from minions"]

    if failed:
        logger.error("FAILED")
        logger.error('\n'.join(str(x) for x in failed))
        return False
    else:
        logger.setLevel(logging.INFO)
        logger.info(["PASSED"])
        return True

def get_nics_csv(delim=","):

    ''' List nics in csv format

    :param delim: Delimiter char. Type: str

    '''

    header = "server,nic_name,ip_addr,mac_addr,link,chassis_id,chassis_name,port_mac,port_descr\n"
    io = ""

    # Try to reuse lldp output if possible
    try:
        lldp_info = Popen("lldpcli -f keyvalue s n s", shell=True, stdout=PIPE).communicate()[0]
    except:
        lldp_info = ""

    for nic in get_nics():
        lldp = ""
        nic_name = nic[0]
        if research('(one|ten|fourty)[0-9]+', nic_name):
            # Check if we can fetch lldp data for that nic
            for line in lldp_info.splitlines():
                chassis = 'lldp.' + nic[0] + '.chassis'
                port = 'lldp.' + nic[0] + '.port'
                if chassis in line or port in line:
                    lldp += delim + line.split('=')[1]
        if not lldp:
            lldp = delim + delim + delim + delim

        io += __salt__['config.get']('id') + \
              delim + nic_name + \
              delim + str(nic[1]).strip() + \
              delim + str(nic[2]).strip() + \
              delim + str(nic[3]).strip() + \
              delim + str(nic[4]).strip() + \
              lldp + "\n"

    return header + io
