import sys
import os
import threading

from scapy import config
config.conf.ipv6_enabled = False

from scapy.all import *
from warmice.services import client


class WarmiceReceiver(threading.Thread):
    def __init__(self, pos=None, group=None, target=None, iface=None):
        threading.Thread.__init__(self, group=group, target=target)
        self._client = client.Client()
        if pos==None:
            self._pos = self._client.getEventPos()
        else:
            self._pos = pos
        self._fdr, self._fdw = os.pipe()
        self._stop = False
        self._iface = iface

    def fileno(self):
        return self._fdr

    def recv(self, size):
        s = os.read(self._fdr, size)
        return Ether(s)

    def stop(self):
        self._stop = True


    def run(self):
        if self._iface=='' or self._iface==None:
            robj = self._client
        else:
            robj = client.VLan(self._iface)
        pos = self._pos
        while not self._stop:
            r = robj.pollEvents(pos, {'type': 'vlan_rx'}, {'type': 'vlan_rx'}, 1, error_on_timeout=False)
            l = len(r['events'])
            if l==0:
                pass
            elif l==1:
                e = r['events'][0]
                data = e['data']
                os.write(self._fdw, data)
                pos = e['pos'] + 1

            else:
                raise AssertionError



_real_sniff = sniff

IFACE_PREFIX="warmice:"

def sniff(iface=None, pos=None, *args, **kwargs):
    if iface==None:
        iface=IFACE_PREFIX

    if iface.startswith(IFACE_PREFIX):
        iface=iface[len(IFACE_PREFIX):]
        rcv = WarmiceReceiver(pos=pos, iface=iface)
        rcv.start()
        exc_info = None
        ret = _real_sniff(opened_socket=rcv, *args, **kwargs)
        rcv.stop()
        rcv.join()
        if exc_info:
            print exc_info
            raise exc_info[1]
        return ret

    else:
        ret = _real_sniff(iface=iface, *args, **kwargs)
        return ret


class WarmiceSender:
    def __init__(self, name=None):
        if name==None:
            name='qemu0.vlan0'
        self._vlan = client.VLan(name)

    def send(self, p):
        self._vlan.send(str(p))

    def close(self):
        del self._vlan




def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, verbose=None, realtime=None, *args, **kargs):
    if iface==None:
        iface='%sqemu0.vlan0' % IFACE_PREFIX

    if iface.startswith(IFACE_PREFIX):
        sndr = WarmiceSender(iface[len(IFACE_PREFIX):])
        ret = scapy.sendrecv.__gen_send(sndr, x, inter=inter, loop=loop, count=count, verbose=verbose, realtime=realtime)
    else:
        ret = scapy.sendrecv.__gen_send(conf.L2socket(iface=iface, *args, **kargs), x, inter=inter, loop=loop, count=count, verbose=verbose, realtime=realtime)
    return ret







def main():
    interact(mydict=globals())
