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


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


def profile(path):
    nvars = nclauses_header = None
    size_hist = collections.Counter()
    pos = neg = 0
    deg = collections.Counter()
    signed_deg = collections.Counter()
    clauses = 0
    first = []
    with open_dimacs(path) as f:
        for line in f:
            if not line or line[0] == "c":
                continue
            if line[0] == "p":
                parts = line.split()
                nvars, nclauses_header = int(parts[2]), int(parts[3])
                continue
            lits = [int(x) for x in line.split() if x != "0"]
            if not lits:
                continue
            clauses += 1
            size_hist[len(lits)] += 1
            if len(first) < 3:
                first.append(lits)
            for lit in lits:
                v = abs(lit)
                deg[v] += 1
                signed_deg[(v, lit > 0)] += 1
                if lit > 0:
                    pos += 1
                else:
                    neg += 1
    degrees = list(deg.values())
    singleton_vars = sum(1 for d in degrees if d == 1)
    max_deg = max(degrees) if degrees else 0
    avg_deg = sum(degrees) / len(degrees) if degrees else 0
    entropy_hist = collections.Counter()
    for v in range(1, (nvars or 0) + 1):
        p = signed_deg[(v, True)]
        q = signed_deg[(v, False)]
        entropy_hist[(p, q)] += 1
    top_patterns = entropy_hist.most_common(8)
    return {
        "file": Path(path).name,
        "nvars": nvars,
        "nclauses_header": nclauses_header,
        "clauses": clauses,
        "size_hist": dict(sorted(size_hist.items())),
        "pos": pos,
        "neg": neg,
        "avg_deg": avg_deg,
        "max_deg": max_deg,
        "singleton_vars": singleton_vars,
        "top_signed_degree_patterns": top_patterns,
        "first": first,
    }


def main():
    for path in sys.argv[1:]:
        p = profile(path)
        print(f"{p['file']}")
        print(f"  vars={p['nvars']} clauses={p['clauses']} header={p['nclauses_header']}")
        print(f"  sizes={p['size_hist']}")
        total = p["pos"] + p["neg"]
        print(f"  lits pos={p['pos']} neg={p['neg']} pos_frac={p['pos']/total if total else 0:.4f}")
        print(f"  degree avg={p['avg_deg']:.2f} max={p['max_deg']} singleton_vars={p['singleton_vars']}")
        pat = ", ".join(f"{k}:{v}" for k, v in p["top_signed_degree_patterns"])
        print(f"  signed_degree_patterns {pat}")
        print(f"  first={p['first']}")


if __name__ == "__main__":
    main()
