#!/usr/bin/env python3

"""
diff-filter denormalizes diff output by having lines beginning with ' ' or '+'
come from file2's unmodified version.
"""

import re
from sys import argv, stdin, stdout


class FileScanner:
    """
    FileScanner is an iterator over the lines of a file.
    It can apply a rewrite rule which can be used to skip lines.
    """

    def __init__(self, file, rewrite=lambda x: x):
        self.file = file
        self.line = 1
        self.rewrite = rewrite

    def __next__(self):
        while True:
            nextline = self.rewrite(next(self.file))
            if nextline is not None:
                self.line += 1
                return nextline


def main():
    # we only test //d rules, as we need to ignore those lines
    regexregex = re.compile(r"^/(?P<rule>.*)/d$")
    regexpipeline = []
    for line in open(argv[1]):
        line = line.strip()
        if not line or line.startswith("#") or not line.endswith("d"):
            continue
        rule = regexregex.match(line)
        if not rule:
            raise "Failed to parse regex rule: %s" % line
        regexpipeline.append(re.compile(rule.group("rule")))

    def sed(line):
        if any(regex.search(line) for regex in regexpipeline):
            return None
        return line

    for line in stdin:
        if line.startswith("+++ "):
            tab = line.rindex("\t")
            fname = line[4:tab]
            file2 = FileScanner(
                open(fname.replace(".modified", ""), encoding="utf8"), sed
            )
            stdout.write(line)
        elif line.startswith("@@ "):
            idx_start = line.index("+") + 1
            idx_end = idx_start + 1
            while line[idx_end].isdigit():
                idx_end += 1
            linenum = int(line[idx_start:idx_end])
            while file2.line < linenum:
                next(file2)
            stdout.write(line)
        elif line.startswith(" "):
            stdout.write(" ")
            stdout.write(next(file2))
        elif line.startswith("+"):
            stdout.write("+")
            stdout.write(next(file2))
        else:
            stdout.write(line)


main()
