import re


def add_filter(query, fields=None, start='', stop=''):
    """Add a filter to the query.

    This method adds a "WHERE" clause to the provided InfluxDB query based
    on the `fields` dictionary. The values of `fields` may be either single
    terms, a regex, or a list, whose individual terms will be ORed together.
    The final list of filters is joined together by a logical AND.

    """
    filters = []
    or_stmt = []
    assert isinstance(fields, dict)
    for key, value in fields.items():
        if isinstance(value, list):
            or_stmt = ['"%s" = \'%s\'' % (key, val) for val in value]
        elif re.match('^/.*/$', value):
            filters.append('"%s" =~ %s' % (key, value))
        else:
            filters.append('"%s" = \'%s\'' % (key, value))
    if or_stmt:
        filters.append('(%s)' % ' OR '.join(or_stmt))
    if stop:
        try:
            stop = str(int(stop)) + 's'
            filters.insert(0, '"time" <= %s' % stop)
        except ValueError:
            filters.insert(0, '"time" <= now() - %s' % stop)
    if start:
        try:
            start = str(int(start)) + 's'
            filters.insert(0, '"time" > %s' % start)
        except ValueError:
            filters.insert(0, '"time" > now() - %s' % start)

    return '%s WHERE %s' % (query, ' AND '.join(filters))