#!/usr/bin/env python3
"""exp15 — build the EXPANDED S2' (full-power, owner decision 2026-07-18) from the first N 节 of 蛊真人.

Produces TWO aligned versions of the same content (only the seam separator differs), + seam ledger:
  S2prime_big_flat.txt        seams = single '\\n'  -> greedy A0 is BLIND (blind-budget cuts)
  S2prime_big_blanklines.txt  seams = '\\n\\n'      -> greedy ORACLE cuts AT every seam (paragraph flush)
Within a 节 the body is normalized to single '\\n' (collapse internal blank lines) so the ONLY '\\n\\n'
are at seams — that is what makes the oracle cut exactly at scene boundaries.

Labels for seams are NOT hand-classified here (too many); Q1b uses the oracle's cut-at-all-seams behavior
and the covariate is per-seam. Deterministic straddle-trap finding happens in straddle_traps.py.
Run: python build_s2prime_big.py [N]   # default N=45
"""
from __future__ import annotations
import json
import re
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
import build_s2prime as B

OUT = Path("/home/ubuntu/books/gu-zhenren/exp15")


def main():
    n = int(sys.argv[1]) if len(sys.argv) > 1 else 45
    secs = B.sections(B.load_text())[:n]
    bodies = []
    for idx, header, body in secs:
        b = body.replace("\r\n", "\n").replace("\r", "\n")
        b = re.sub(r"\n{2,}", "\n", b).strip("\n")   # single-\n within 节
        bodies.append((idx, b))
    flat = "\n".join(b for _, b in bodies)
    blank = "\n\n".join(b for _, b in bodies)

    # seam offsets in each version (start of body i, i>0)
    def seam_offsets(sep):
        offs, cur = [], 0
        for i, (idx, b) in enumerate(bodies):
            if i > 0:
                cur += len(sep)
            if i > 0:
                offs.append({"seam_id": i, "prev_sec": bodies[i - 1][0], "next_sec": idx, "rune_offset": cur})
            cur += len(b)
        return offs

    (OUT / "S2prime_big_flat.txt").write_text(flat, encoding="utf-8")
    (OUT / "S2prime_big_blanklines.txt").write_text(blank, encoding="utf-8")
    (OUT / "S2prime_big_seams_flat.json").write_text(json.dumps(
        {"version": "flat", "n_sections": n, "section_ids": [b[0] for b in bodies],
         "total_runes": len(flat), "seams": seam_offsets("\n")}, ensure_ascii=False, indent=2), encoding="utf-8")
    (OUT / "S2prime_big_seams_blank.json").write_text(json.dumps(
        {"version": "blanklines", "n_sections": n, "section_ids": [b[0] for b in bodies],
         "total_runes": len(blank), "seams": seam_offsets("\n\n")}, ensure_ascii=False, indent=2), encoding="utf-8")
    print(f"S2'-big: {n}节  flat={len(flat)} runes  blank={len(blank)} runes  seams={n-1}")
    # verify seam alignment
    fs = seam_offsets("\n"); bs = seam_offsets("\n\n")
    ok = all(flat[s["rune_offset"]:s["rune_offset"]+3] == bodies[i+1][1][:3] for i, s in enumerate(fs))
    okb = all(blank[s["rune_offset"]:s["rune_offset"]+3] == bodies[i+1][1][:3] for i, s in enumerate(bs))
    print(f"seam alignment: flat={ok} blank={okb}")


if __name__ == "__main__":
    main()
