"""Provision a reviewed repository reader and its signed Linux launch material.

Supply matching Chio binaries and an operator-owned rollback anchor on a separate
persistent device. The script creates fresh demonstration keys and private state.
It never reuses a failed or existing profile, changes runtime code or installs a VM.
"""
import argparse
import hashlib
import json
import os
from pathlib import Path
import shutil
import subprocess

p = argparse.ArgumentParser(description=__doc__)
p.add_argument('--directory', type=Path, required=True)
p.add_argument('--chio', default='chio')
p.add_argument('--reader', type=Path, required=True)
p.add_argument('--helper', type=Path, required=True)
p.add_argument('--anchor-root', type=Path, required=True)
a = p.parse_args()
os.umask(0o077)
root = a.directory.resolve()
reader, helper = a.reader.resolve(strict=True), a.helper.resolve(strict=True)
chio = Path(shutil.which(a.chio) or a.chio).resolve(strict=True)
anchor = a.anchor_root.resolve(strict=True)
assert anchor.is_dir(), 'operator must provision the rollback anchor directory first'
root.mkdir(mode=0o700, parents=True, exist_ok=False)
assert anchor.stat().st_dev != root.stat().st_dev, 'rollback anchor must be on a separate device'
for name in ['repository', 'connection', 'setup-results']:
    (root / name).mkdir(mode=0o700)
(root / 'repository/README.md').write_text('Review this repository under the retained read grant.\n')
(root / 'private.txt').write_text('This adjacent file is outside the repository grant.\n')
commands = []

def run(name, command, input_text=None):
    command = [str(x) for x in command]
    result = subprocess.run(command, input=input_text, text=True, capture_output=True, timeout=180)
    (root / 'setup-results' / (name + '.stdout')).write_text(result.stdout)
    (root / 'setup-results' / (name + '.stderr')).write_text(result.stderr)
    commands.append({'name': name, 'command': command, 'exit': result.returncode})
    (root / 'setup-results/commands.json').write_text(json.dumps(commands, indent=2) + '\n')
    if result.returncode:
        raise RuntimeError(f'{name} failed; retain this directory and inspect setup-results/{name}.stderr')
    return result.stdout

messages = [
    {'jsonrpc': '2.0', 'id': 1, 'method': 'initialize', 'params': {
        'protocolVersion': '2025-11-25', 'capabilities': {},
        'clientInfo': {'name': 'chio-reader-review', 'version': '1'}}},
    {'jsonrpc': '2.0', 'method': 'notifications/initialized'},
    {'jsonrpc': '2.0', 'id': 2, 'method': 'tools/list', 'params': {}},
]
listing = run('review-tools', [reader, '--root', root / 'repository'],
              '\n'.join(json.dumps(item) for item in messages) + '\n')
responses = [json.loads(line) for line in listing.splitlines() if line.strip()]
tools = next(item['result'] for item in responses if item.get('id') == 2)
assert sorted(tool['name'] for tool in tools['tools']) == ['list_directory', 'read_file', 'stat']
fixture = root / 'reviewed-tools.json'
fixture.write_text(json.dumps(tools, indent=2) + '\n')
launch = root / 'launch'
command = [chio, 'security', 'provision-reference-runtime', '--stage', 'enforced',
           '--output-dir', launch, '--cage-init', helper, '--max-artifact-bytes', '67108864',
           '--receipt-rollback-anchor-root', anchor, '--tools-fixture', fixture,
           '--target', reader, '--target-arg', '--root', '--target-arg', root / 'repository',
           '--read-path', root / 'repository', '--working-directory', root,
           '--execution-uid', os.getuid(), '--execution-gid', os.getgid(),
           '--server-id', 'workspace', '--server-name', 'Larkfield pricing workspace',
           '--server-version', '1']
for gid in sorted(set(os.getgroups()) - {os.getgid()}):
    command += ['--execution-supplementary-gid', gid]
provision = json.loads(run('provision', command))
manifest_pin = provision['manifestPublicKey']
policy_pin = provision['cagePolicyPublicKey']
assert manifest_pin == (launch / 'manifest-public-key').read_text().strip()
assert policy_pin == (launch / 'cage-policy-signer').read_text().strip()
(root / 'public-pins.json').write_text(json.dumps({
    'manifestPublicKey': manifest_pin, 'cagePolicyPublicKey': policy_pin,
    'source': 'Operator provisioning result, cross-checked against separate public-key files'}, indent=2) + '\n')
policy = root / 'policy.yaml'
policy.write_text('''kernel:
  max_capability_ttl: 3600
  delegation_depth_limit: 8
  durable_admission_mode: all
capabilities:
  default:
    tools:
      - server: workspace
        tool: read_file
        operations: [invoke, delegate]
        max_invocations: 6
        ttl: 3600
''')
config = {'schema': 'chio.process.host.v1', 'policy': str(policy), 'servers': [{
    'id': 'workspace', 'command': [str(reader), '--root', str(root / 'repository')],
    'request_timeout_seconds': 30, 'launch_policy': str(launch / 'cage-launch-policy.json'),
    'launch_policy_signer': policy_pin}], 'limits': {'max_calls': 6, 'max_processes': 1, 'max_depth': 0},
    'execution_nonces': True}
(root / 'host-config.json').write_text(json.dumps(config, indent=2) + '\n')
run('host-init', [chio, 'process', 'init', '--config', root / 'host-config.json',
                  '--state', root / 'host', '--aggregate-invocations', '6'])
# No connection credential or private seed is included in this record.
profile = {'root': str(root), 'reader': str(reader), 'helper': str(helper), 'chio': str(chio),
           'anchorRoot': str(anchor), 'binaries': {p.name: hashlib.sha256(p.read_bytes()).hexdigest()
                                                for p in [chio, reader, helper]}}
(root / 'profile.json').write_text(json.dumps(profile, indent=2) + '\n')
print(json.dumps({'prepared': True, 'root': str(root),
                  'next': 'Select the original host-init launch receipt and verify it against your independent pins.'}))
