#!/usr/bin/env python3
import lzma
import sys
from collections import Counter, defaultdict


def ints_from_file(path):
    with lzma.open(path, "rt", encoding="ascii", errors="strict") as f:
        for line in f:
            if not line or line[0] == "c":
                continue
            if line[0] == "p":
                parts = line.split()
                yield ("p", int(parts[2]), int(parts[3]))
            else:
                for tok in line.split():
                    yield int(tok)


def profile(path):
    vars_n = clauses_n = None
    lens = Counter()
    long_lens = Counter()
    first_long = []
    pos = neg = lits = 0
    cur = []
    clause_idx = 0
    var_pos = Counter()
    var_neg = Counter()
    first_clauses = []
    for item in ints_from_file(path):
        if isinstance(item, tuple):
            _, vars_n, clauses_n = item
            continue
        lit = item
        if lit == 0:
            n = len(cur)
            lens[n] += 1
            if n > 9:
                long_lens[n] += 1
                if len(first_long) < 6:
                    first_long.append((clause_idx, cur[:]))
            if len(first_clauses) < 12:
                first_clauses.append(cur[:])
            clause_idx += 1
            cur = []
        else:
            cur.append(lit)
            lits += 1
            if lit > 0:
                pos += 1
                var_pos[lit] += 1
            else:
                neg += 1
                var_neg[-lit] += 1
    degrees = Counter()
    pure = 0
    for v in range(1, vars_n + 1):
        d = var_pos[v] + var_neg[v]
        degrees[d] += 1
        if d and (var_pos[v] == 0 or var_neg[v] == 0):
            pure += 1
    print(path)
    print(f"vars={vars_n} clauses={clauses_n} parsed={clause_idx} lits={lits} avg={lits/clauses_n:.6f} pos_frac={pos/(pos+neg):.6f}")
    print("lens", " ".join(f"{k}:{v}" for k, v in sorted(lens.items())))
    print("long_lens", " ".join(f"{k}:{v}" for k, v in sorted(long_lens.items())))
    print("degree_top", " ".join(f"{k}:{v}" for k, v in degrees.most_common(20)))
    print(f"pure={pure}")
    print("first_clauses")
    for i, cl in enumerate(first_clauses):
        print(i, len(cl), " ".join(map(str, cl[:25])))
    print("first_long")
    for ci, cl in first_long:
        print(ci, len(cl), " ".join(map(str, cl[:30])))


if __name__ == "__main__":
    for p in sys.argv[1:]:
        profile(p)
