
from vpp_object import VppObject
import socket


class IGMP_MODE:
    ROUTER = 0
    HOST = 1


class IGMP_FILTER:
    INCLUDE = 1
    EXCLUDE = 0


def find_igmp_state(states, itf, gaddr, saddr):
    for s in states:
        if s.sw_if_index == itf.sw_if_index and \
           s.gaddr.address == socket.inet_pton(socket.AF_INET, gaddr) and \
           s.saddr.address == socket.inet_pton(socket.AF_INET, saddr):
            return True
    return False


def wait_for_igmp_event(test, timeout, itf, gaddr, saddr, ff):
    ev = test.vapi.wait_for_event(timeout, "igmp_event")
    if ev.sw_if_index == itf.sw_if_index and \
       ev.gaddr.address == socket.inet_pton(socket.AF_INET, gaddr) and \
       ev.saddr.address == socket.inet_pton(socket.AF_INET, saddr) and \
       ev.filter == ff:
        return True
    return False


class IgmpSG():
    def __init__(self, gaddr, saddrs):
        self.gaddr = gaddr
        self.gaddr_p = socket.inet_pton(socket.AF_INET, gaddr)
        self.saddrs = saddrs
        self.saddrs_p = []
        self.saddrs_encoded = []
        for s in saddrs:
            ss = socket.inet_pton(socket.AF_INET, s)
            self.saddrs_p.append(ss)
            self.saddrs_encoded.append({'address': ss})


class IgmpRecord():
    def __init__(self, sg, type):
        self.sg = sg
        self.type = type


class VppHostState(VppObject):
    def __init__(self, test, filter, sw_if_index, sg):
        self._test = test
        self.sw_if_index = sw_if_index
        self.filter = filter
        self.sg = sg

    def add_vpp_config(self):
        self._test.vapi.igmp_listen(
            self.filter, self.sw_if_index,
            self.sg.saddrs_encoded, self.sg.gaddr_p)

    def remove_vpp_config(self):
        self._test.vapi.igmp_listen(
            self.filter,
            self.sw_if_index,
            [],
            self.sg.gaddr_p)

    def __str__(self):
        return self.object_id()

    def object_id(self):
        return "%s:%d" % (self.sg, self.sw_if_index)

    def query_vpp_config(self):
        return self._test.vapi.igmp_dump()
