import re
SCR = r'C:/Users/decid/AppData/Local/Temp/claude/C--Users-decid-Documents-projects-spt-core/646ca2c9-443e-4993-8707-ba17cf7e661f/scratchpad/'
p = 'crates/spt-daemon/src/resting.rs'
s = open(p, encoding='utf-8', newline='').read()
crlf = '\r\n' in s
s = s.replace('\r\n', '\n')

# 1. replace the three old table/auto-suspend/knob tests with the new block
a = s.index('    // [unit->REQ-INST-3] THE transition table — the CONTEXT state diagram as')
b = s.index('    // [unit->REQ-INST-4] the transition echo fires EXACTLY ONCE per')
s = s[:a] + open(SCR + 'w1_tabletests.rs', encoding='utf-8').read() + s[b:]

tests_at = s.index('#[cfg(test)]\nmod tests {')
head, tests = s[:tests_at], s[tests_at:]


def insert_arg(text, fname, after_idx, arg):
    out = []
    i = 0
    pat = re.compile(r'\b' + re.escape(fname) + r'\(')
    while True:
        m = pat.search(text, i)
        if not m:
            out.append(text[i:])
            break
        # skip definitions
        if text[max(0, m.start() - 7):m.start()].endswith('fn '):
            out.append(text[i:m.end()])
            i = m.end()
            continue
        start = m.end()
        depth = 0
        j = start
        commas = []
        while True:
            c = text[j]
            if c in '([{':
                depth += 1
            elif c in ')]}':
                if depth == 0:
                    break
                depth -= 1
            elif c == ',' and depth == 0:
                commas.append(j)
            elif c == '|' and depth == 0:
                pass
            j += 1
        if len(commas) <= after_idx:
            raise SystemExit(f'too few args at {text[m.start():m.start()+80]!r}')
        pos = commas[after_idx] + 1
        seg = text[commas[after_idx - 1] + 1 if after_idx else start:commas[after_idx]]
        if '\n' in text[commas[after_idx]:commas[after_idx] + 40].split(',')[0] or '\n' in seg:
            # multi-line call: copy the indentation of the next arg line
            nxt = text[pos:]
            ind = re.match(r'\n([ \t]*)', nxt)
            ins = '\n' + (ind.group(1) if ind else '            ') + arg + ','
        else:
            ins = ' ' + arg + ','
        out.append(text[i:pos] + ins)
        i = pos
    return ''.join(out)


# closures contain `||` and commas inside `{}` — depth handles braces; `|| {}`
# has no top-level comma. apply_event(path, event, knob, <siblings>, now, ...)
tests = insert_arg(tests, 'apply_event', 2, 'SiblingView::default()')
tests = insert_arg(tests, 'apply_event_with_liveness', 2, 'SiblingView::default()')
tests = tests.replace('RestEvent::Detach', 'RestEvent::SiblingActivated')
s = head + tests
if crlf:
    s = s.replace('\n', '\r\n')
open(p, 'w', encoding='utf-8', newline='').write(s)
print('ok')
