from __future__ import print_function
from twisted.internet import inotify
from twisted.python.filepath import FilePath
from twisted.internet.task import react, deferLater
from twisted.internet.defer import inlineCallbacks

import shutil
from os.path import join

@inlineCallbacks
def main(reactor):
    notifier = inotify.INotify()
    notifier.startReading()
    IN_EXCL_UNLINK = 0x04000000L  # copied from tahoe stuff; why not in inotify?
    mask = ( inotify.IN_CREATE
             | inotify.IN_CLOSE_WRITE
             | inotify.IN_MOVED_TO
             | inotify.IN_MOVED_FROM
             | inotify.IN_DELETE
             | inotify.IN_ONLYDIR
    #         | IN_EXCL_UNLINK
    )

    notifies = []
    def notify_callback(_, filepath, mask):
        print("notify callback", inotify.humanReadableMask(mask))
        notifies.append((filepath, inotify.humanReadableMask(mask)))

    local_dir = './foo-inotify'
    fp = FilePath(local_dir)
    print("XXXX", fp)
    z = notifier.watch(
        fp,
        mask=mask,
        callbacks=[notify_callback],
        recursive=True,
    )
    print("ZZZ", z)

    p0 = join(local_dir, 'file0')
    p1 = join(local_dir, 'file1')
    yield deferLater(reactor, 1, lambda: None)
    print("0", notifies)
    with open(p0, 'wb') as f:
        yield deferLater(reactor, 1, lambda: None)
        print("1", notifies)
        f.write('ohai\n')
        yield deferLater(reactor, 1, lambda: None)
        print("2", notifies)
        f.flush()
        yield deferLater(reactor, 1, lambda: None)
        print("3", notifies)
        shutil.move(p0, p1)
        yield deferLater(reactor, 1, lambda: None)
        print("4", notifies)
    yield deferLater(reactor, 1, lambda: None)
    print("5", notifies)

    for (path, mask) in notifies:
        print(' {} -> {}'.format(path, mask))

react(main)
