import fnmatch


def is_matching(filename, patterns=None):
    """Check if a filename matches the list of positive and negative patterns.

    Positive patterns are strings like ``"1.txt"``, ``"[23].txt"``, or
    ``"*.txt"``.

    Negative patterns are strings like ``"!1.txt"``, ``"![23].txt"``, or
    ``"!*.txt"``.

    Each pattern is checked in turn, so the list of patterns ``["!*.txt",
    "1.txt"]`` will still match ``"1.txt"``.

    >>> from django_remote_submission.tasks import is_matching
    >>> is_matching("1.txt", patterns=["1.txt"])
    True
    >>> is_matching("1.txt", patterns=["[12].txt"])
    True
    >>> is_matching("1.txt", patterns=["*.txt"])
    True
    >>> is_matching("1.txt", patterns=["1.txt", "!*.txt"])
    False
    >>> is_matching("1.txt", patterns=["!*.txt", "[12].txt"])
    True

    """
    if patterns is None:
        patterns = ['*']

    is_matching = False

    for pattern in patterns:
        if not pattern.startswith('!'):
            if fnmatch.fnmatch(filename, pattern):
                is_matching = True
        else:
            if fnmatch.fnmatch(filename, pattern[1:]):
                is_matching = False

    return is_matching