import re
import os

end_space = re.compile(r"([^\\]\s)*$")


def fnmatch_translate(pat, path_name=False):
    parts = []
    seq = False
    i = 0
    if pat[0] == "/" or path_name:
        parts.append("^")
        any_char = "[^/]"
        if pat[0] == "/":
            pat = pat[1:]
    else:
        any_char = "."
        parts.append("^(?:.*/)?")
    if pat[-1] == "/":
        # If the last character is / match this directory or any subdirectory
        pat = pat[:-1]
        suffix = "(?:/|$)"
    else:
        suffix = "$"
    while i < len(pat):
        c = pat[i]
        if c == "\\":
            if i < len(pat) - 1:
                i += 1
                c = pat[i]
                parts.append(re.escape(c))
            else:
                raise ValueError
        elif seq:
            if c == "]":
                seq = False
                # First two cases are to deal with the case where / is the only character
                # in the sequence but path_name is True so it shouldn't match anything
                if parts[-1] == "[":
                    parts = parts[:-1]
                elif parts[-1] == "^" and parts[-2] == "[":
                    parts = parts[:-2]
                else:
                    parts.append(c)
            elif c == "-":
                parts.append(c)
            elif not (path_name and c == "/"):
                parts += re.escape(c)
        elif c == "[":
            parts.append("[")
            if i < len(pat) - 1 and pat[i+1] in ("!", "^"):
                parts.append("^")
                i += 1
            seq = True
        elif c == "*":
            if i < len(pat) - 1 and pat[i+1] == "*":
                parts.append(any_char + "*")
                i += 1
                if i < len(pat) - 1 and pat[i+1] == "*":
                    raise ValueError
            else:
                parts.append(any_char + "*")
        elif c == "?":
            parts.append(any_char)
        else:
            parts.append(re.escape(c))
        i += 1

    if seq:
        raise ValueError
    parts.append(suffix)
    try:
        return re.compile("".join(parts))
    except Exception:
        raise


def parse_line(line):
    line = line.rstrip()
    if not line or line[0] == "#":
        return

    invert = line[0] == "!"
    if invert:
        line = line[1:]

    dir_only = line[-1] == "/"

    if dir_only:
        line = line[:-1]

    return invert, dir_only, fnmatch_translate(line, dir_only)


class PathFilter(object):
    def __init__(self, root, extras=None):
        if root:
            ignore_path = os.path.join(root, ".gitignore")
        else:
            ignore_path = None
        if not ignore_path and not extras:
            self.trivial = True
            return
        self.trivial = False

        self.rules_file = []
        self.rules_dir = []

        if extras is None:
            extras = []

        if ignore_path and os.path.exists(ignore_path):
            self._read_ignore(ignore_path)

        for item in extras:
            self._read_line(item)

    def _read_ignore(self, ignore_path):
        with open(ignore_path) as f:
            for line in f:
                self._read_line(line)

    def _read_line(self, line):
        parsed = parse_line(line)
        if not parsed:
            return
        invert, dir_only, regexp = parsed
        if dir_only:
            self.rules_dir.append((regexp, invert))
        else:
            self.rules_file.append((regexp, invert))

    def __call__(self, path):
        if os.path.sep != "/":
            path = path.replace(os.path.sep, "/")

        if self.trivial:
            return True

        path_is_dir = path[-1] == "/"
        if path_is_dir:
            path = path[:-1]
            rules = self.rules_dir
        else:
            rules = self.rules_file

        include = True
        for regexp, invert in rules:
            if not include and invert and regexp.match(path):
                include = True
            elif include and not invert and regexp.match(path):
                include = False
        return include
