#!/usr/bin/python

import os
import sys
import re
import argparse
import logging

import notmuch


def parse_args():
    p = argparse.ArgumentParser()

    p.add_argument('--database', '-d')
    p.add_argument('--verbose', '-v', action='store_true')
    p.add_argument('--dryrun', '-n', action='store_true')

    return p.parse_args()


def parse_timespec(ts):
    mo = re.match('(\d+)([dwmy])', ts)
    if not mo:
        raise ValueError('invalid time spec: %s' % ts)

    val = int(mo.group(1))
    unit = mo.group(2)

    if unit == 'd':
        pass
    elif unit == 'w':
        val *= 7
    elif unit == 'y':
        val *= 365

    return val


def main():
    args = parse_args()
    logging.basicConfig(
            format='%(asctime)s %(name)s %(levelname)s: %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
            level=logging.INFO if args.verbose else logging.WARN)

    log = logging.getLogger('expire-messages')

    db = notmuch.database.Database(args.database,
            mode=notmuch.database.Database.MODE.READ_WRITE)

    expiretags = []
    for tag in db.get_all_tags():
        if tag.startswith('expire:'):
            expiretags.append(tag)

    log.info('found expire tags: %s', ', '.join(expiretags))

    for tag in expiretags:
        timespec = parse_timespec(tag.split(':')[1])
        search = 'NOT tag:flagged AND NOT tag:keep AND tag:%s AND date:..%s_days' % (tag, timespec)
        log.info('searching for %s (expire older than %s days)' % (
            search,
            timespec))

        try:
            q = db.create_query(search)
        except notmuch.errors.NullPointerError:
            log.info('no messages.')

        db.begin_atomic()
        for msg in q.search_messages():
            fn = msg.get_filename()
            if args.verbose:
                log.info('removing message %s (%s)',
                         msg.get_message_id(),
                         fn)
            if args.dryrun:
                continue

            db.remove_message(fn)
            os.unlink(fn)
        db.end_atomic()

    db.close()


if __name__ == '__main__':
    main()
