from django.core.management.base import BaseCommand

from services.models import Switch
from djadhere.utils import from_livestatus

import re


class Command(BaseCommand):
    help = 'Récupération du dernier ping depuis check_mk'

    def handle(self, *args, **options):
        dell_iface_regex = re.compile('^Interface TenGigabitEthernet 0/(?P<id>[0-9]+)$')
        ubnt_iface_regex = re.compile('^Interface Slot: 0 Port: (?P<id>[0-9]+) (Gigabit|10G) - Level$')
        status_regex = re.compile('^OK .* \((?P<status>up|down)\)')
        for sw in Switch.objects.all():
            up, down = [], []
            hosts = from_livestatus('hosts', query=['Filter: host_name = %s' % sw.name], columns=['services_with_info'])
            if len(hosts) != 1:
                return
            host = hosts[0]
            for service in host.services_with_info:
                description, _, _, info = service
                g = dell_iface_regex.match(description)
                if not g:
                    g = ubnt_iface_regex.match(description)
                if not g:
                    continue
                port = int(g.group('id'))
                if port < sw.first_port or port > sw.last_port:
                    continue
                g = status_regex.match(info)
                if not g:
                    continue
                status = g.group('status')
                if status == 'up':
                    up.append(port)
                else:
                    assert(status == 'down')
                    down.append(port)
            unknown = set(range(sw.first_port, sw.last_port + 1)) - set(up) - set(down)
            upped = sw.ports.filter(port__in=up).exclude(up=True).update(up=True)
            downed = sw.ports.filter(port__in=down).exclude(up=False).update(up=False)
            unknowned = sw.ports.filter(port__in=unknown).exclude(up__isnull=True).update(up=None)
            #print("Switch %s: UP: %d (%+d), DOWN: %d (%+d), UNKNOWN: %d (%+d)" \
            #        % (sw.name, len(up), upped, len(down), downed, len(unknown), unknowned))