#!/usr/bin/env python3
"""Whitespace-normalised, line-numbered diff of the CoSER e-print versions. Reads paths given on argv; writes to stdout."""
import difflib, os, re, sys

base = sys.argv[1]
pairs = [('v1', 'v2'), ('v2', 'v3')]


def files(v):
    out = set()
    root = os.path.join(base, v)
    for d, _, fs in os.walk(root):
        for f in fs:
            if f.endswith(('.tex', '.bbl')):
                out.add(os.path.relpath(os.path.join(d, f), root))
    return out


def lines(path):
    with open(path, encoding='utf-8', errors='replace') as f:
        return [l.rstrip('\n') for l in f]


def norm(l):
    return re.sub(r'\s+', ' ', l).strip()


for a, b in pairs:
    fa, fb = files(a), files(b)
    print(f'######## {a} -> {b}')
    print('only in', a, sorted(fa - fb))
    print('only in', b, sorted(fb - fa))
    for rel in sorted(fa & fb):
        la = lines(os.path.join(base, a, rel))
        lb = lines(os.path.join(base, b, rel))
        na = [(i + 1, norm(l)) for i, l in enumerate(la) if norm(l)]
        nb = [(i + 1, norm(l)) for i, l in enumerate(lb) if norm(l)]
        sm = difflib.SequenceMatcher(None, [x[1] for x in na], [x[1] for x in nb], autojunk=False)
        ops = [o for o in sm.get_opcodes() if o[0] != 'equal']
        if not ops:
            print(f'== {rel}: identical after whitespace normalisation')
            continue
        print(f'-- {rel}: {len(ops)} changes')
        for tag, i1, i2, j1, j2 in ops:
            for n, t in na[i1:i2]:
                print(f'  - {a}:{n}: {t[:600]}')
            for n, t in nb[j1:j2]:
                print(f'  + {b}:{n}: {t[:600]}')
