"""Export the reviewed public fixture through Sonny's real document tools.
Run in the fixture directory: python3 export-brief.py --export
Requires Sonny 0.12.7 on PATH. No model, network integration or API key needed.
"""
import argparse
import hashlib
import json
from pathlib import Path
import queue
import subprocess
import threading

parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--export', action='store_true', help='approve host document-tool effects and create review-brief.pdf in this directory')
args = parser.parse_args()
if not args.export:
    parser.error('review approved-brief.md, then pass --export to approve the local PDF write')
root = Path.cwd().resolve()
source = root / 'approved-brief.md'
output = root / 'review-brief.pdf'
if source.is_symlink() or not source.is_file():
    parser.error('approved-brief.md must be a regular local file')
if output.exists() or output.is_symlink():
    parser.error('review-brief.pdf already exists; inspect it and choose a fresh directory')
content = source.read_text()
if len(content.encode()) > 65536:
    parser.error('this example accepts at most 64 KiB')
original = hashlib.sha256(source.read_bytes()).hexdigest()
# Inherit operator configuration and trusted policy. This flag explicitly grants
# host effects; it does not establish realm containment or override policy.
process = subprocess.Popen(['sonny', 'mcp-server', '--allow-host-effects', '--allowed-tools',
                            'doc_write,doc_read,doc_validate,doc_inspect'],
                           stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, bufsize=1)
lines = queue.Queue()
def read_stdout():
    for line in process.stdout:
        lines.put(line)
    lines.put(None)
threading.Thread(target=read_stdout, daemon=True).start()
sequence = 0
receipts = []
def rpc(method, params, notify=False):
    global sequence
    frame = {'jsonrpc': '2.0', 'method': method, 'params': params}
    if not notify:
        sequence += 1
        frame['id'] = sequence
    process.stdin.write(json.dumps(frame) + '\n')
    process.stdin.flush()
    if notify:
        return
    while True:
        line = lines.get(timeout=40)
        if line is None:
            raise RuntimeError('Sonny closed the protocol stream; inspect stderr')
        response = json.loads(line)
        if response.get('id') != sequence:
            continue
        if 'error' in response:
            raise RuntimeError(response['error'])
        return response['result']
def call(name, arguments):
    result = rpc('tools/call', {'name': name, 'arguments': arguments})
    if result.get('isError'):
        raise RuntimeError(result)
    texts = [item['text'] for item in result.get('content', []) if item.get('type') == 'text']
    if len(texts) != 1:
        raise RuntimeError('expected one structured document result')
    payload = json.loads(texts[0])
    receipts.append({'tool': name, 'result': payload})
    if payload.get('error') or payload.get('success') is False:
        raise RuntimeError(payload)
    return payload
try:
    rpc('initialize', {'protocolVersion': '2024-11-05', 'capabilities': {}, 'clientInfo': {'name': 'reviewed-brief-export', 'version': '1'}})
    rpc('notifications/initialized', {}, notify=True)
    listed = rpc('tools/list', {})
    if {tool['name'] for tool in listed['tools']} != {'doc_write', 'doc_read', 'doc_validate', 'doc_inspect'}:
        raise RuntimeError('the exact four-tool surface is unavailable; do not broaden it')
    written = call('doc_write', {'path': output.name, 'content': content, 'expected_absent': True, 'title': 'Support pilot review', 'page_size': 'letter'})
    if written.get('effect') != 'created' or not output.is_file():
        raise RuntimeError('PDF creation was not confirmed')
    validated = call('doc_validate', {'path': output.name})
    if validated.get('valid') is not True:
        raise RuntimeError('PDF structural validation failed')
    read = call('doc_read', {'path': output.name, 'as': 'text'})
    if read.get('coverage') != 'full' or not read.get('content', '').strip():
        raise RuntimeError('a full, non-empty PDF read-back was not confirmed')
    if hashlib.sha256(source.read_bytes()).hexdigest() != original:
        raise RuntimeError('the approved source changed')
    print(json.dumps({'output': output.name, 'sha256': hashlib.sha256(output.read_bytes()).hexdigest(), 'source_unchanged': True, 'receipts': receipts}, indent=2))
    print('Open review-brief.pdf and inspect every page before sharing.')
finally:
    process.stdin.close()
    try:
        process.wait(timeout=5)
    except subprocess.TimeoutExpired:
        process.terminate()
        process.wait(timeout=5)
