#!/usr/bin/env python3
import collections
import lzma
import sys
from pathlib import Path


def open_dimacs(path: Path):
    if path.suffix == ".xz":
        return lzma.open(path, "rt", encoding="ascii")
    return path.open("rt", encoding="ascii")


def parse(path: Path):
    nvars = nclauses = None
    size_counts = collections.Counter()
    pos = collections.Counter()
    neg = collections.Counter()
    units = []
    clauses = 0
    with open_dimacs(path) as f:
        pending = []
        for line in f:
            if not line or line[0] == "c":
                continue
            if line[0] == "p":
                parts = line.split()
                nvars = int(parts[2])
                nclauses = int(parts[3])
                continue
            for tok in line.split():
                lit = int(tok)
                if lit == 0:
                    if pending:
                        clauses += 1
                        size_counts[len(pending)] += 1
                        if len(pending) == 1:
                            units.append(pending[0])
                        for x in pending:
                            if x > 0:
                                pos[x] += 1
                            else:
                                neg[-x] += 1
                        pending = []
                    continue
                pending.append(lit)
    return nvars, nclauses, clauses, size_counts, pos, neg, units


def main():
    for arg in sys.argv[1:]:
        path = Path(arg)
        nvars, nclauses, clauses, size_counts, pos, neg, units = parse(path)
        deg = [pos[i] + neg[i] for i in range(1, nvars + 1)]
        used = sum(1 for d in deg if d)
        pure_pos = sum(1 for i in range(1, nvars + 1) if pos[i] and not neg[i])
        pure_neg = sum(1 for i in range(1, nvars + 1) if neg[i] and not pos[i])
        print(path.name)
        print(f"  header vars={nvars} clauses={nclauses} parsed={clauses}")
        print(f"  sizes={dict(sorted(size_counts.items()))}")
        print(f"  units={len(units)} first_units={units[:40]}")
        print(f"  used_vars={used} pure_pos={pure_pos} pure_neg={pure_neg}")
        if deg:
            sdeg = sorted(deg)
            print(
                "  degree min/p50/p90/p99/max="
                f"{sdeg[0]}/{sdeg[len(sdeg)//2]}/{sdeg[int(len(sdeg)*0.90)]}/"
                f"{sdeg[int(len(sdeg)*0.99)]}/{sdeg[-1]}"
            )
        top = sorted(
            ((pos[i] + neg[i], i, pos[i], neg[i]) for i in range(1, nvars + 1)),
            reverse=True,
        )[:12]
        print("  top_degree=" + " ".join(f"{v}:{d}(+{p}/-{q})" for d, v, p, q in top))


if __name__ == "__main__":
    main()
