"""Parameterized camera24 capture helper; one recording, no control API writes."""
import argparse
import datetime
import hashlib
import json
import pathlib
import re
import shutil
import subprocess
import time

import yaml

parser = argparse.ArgumentParser()
parser.add_argument('--camera-id', type=int, required=True)
parser.add_argument('--seconds', type=int, required=True)
parser.add_argument('--scenario', required=True)
parser.add_argument('--root', type=pathlib.Path, default=pathlib.Path('/work'))
parser.add_argument('--source', type=pathlib.Path, default=pathlib.Path('/source/streams_runtime.yaml'))
args = parser.parse_args()
assert args.camera_id > 0 and 1 <= args.seconds <= 300, 'Invalid bounded capture request'
assert shutil.which('ffmpeg'), 'Capture tool is unavailable; no RTSP connection attempted'
root = args.root
for name in ('inputs', 'reports'):
    (root / name).mkdir(exist_ok=True)
assert shutil.disk_usage(root).free >= 15 * 1024**3, 'Insufficient disk space'
raw = args.source.read_bytes()
rows = yaml.safe_load(raw)['added']
rows = list(rows.values()) if isinstance(rows, dict) else rows
matches = [r for r in rows if str(r.get('camera_id', r.get('source_id'))) == str(args.camera_id)]
assert len(matches) == 1, 'Expected exactly one camera registration'
spec = matches[0]
assert hashlib.sha256(str(spec.get('uri','')).encode()).hexdigest() == args.scenario, 'Input fingerprint changed'
uri = spec.get('uri')
assert isinstance(uri, str) and uri.startswith(('rtsp://', 'rtsps://')), 'Expected RTSP input'
dest = root / f'inputs/camera{args.camera_id}_original.mp4'
report = root / 'reports/capture.json'
assert not dest.exists() and not report.exists(), 'Existing recording or report will not be overwritten'
summary = dict(camera_id=args.camera_id, scenario=args.scenario,
    config_sha256=hashlib.sha256(raw).hexdigest(),
    source_sha256=hashlib.sha256(uri.encode()).hexdigest(),
    started_utc=datetime.datetime.now(datetime.timezone.utc).isoformat(),
    requested_seconds=args.seconds, wall_timeout_seconds=args.seconds + 60,
    mode='tcp_video_streamcopy_no_rate_conversion')
command = ['ffmpeg', '-nostdin', '-hide_banner', '-loglevel', 'error', '-n',
    '-rtsp_transport', 'tcp', '-timeout', '15000000', '-i', uri,
    '-map', '0:v:0', '-an', '-t', str(args.seconds), '-c:v', 'copy',
    '-avoid_negative_ts', 'make_zero', '-movflags', '+faststart', str(dest)]
started = time.monotonic()
try:
    result = subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
                            timeout=args.seconds + 60)
    summary['returncode'] = result.returncode
    errors = result.stderr.decode(errors='replace')
    summary['stderr'] = re.sub(r'[a-zA-Z]+://[^\s]+', '<endpoint omitted>', errors)[-3000:]
except subprocess.TimeoutExpired:
    summary['returncode'] = 'TIMEOUT'
    summary['stderr'] = 'Capture exceeded bounded wall timeout; no retry was attempted.'
except OSError:
    summary['returncode'] = 'EXEC_UNAVAILABLE'
    summary['stderr'] = 'Could not launch capture process; no retry was attempted.'
summary['wall_seconds'] = round(time.monotonic() - started, 3)
summary['bytes'] = dest.stat().st_size if dest.exists() else 0
report.write_text(json.dumps(summary, indent=2))
print(json.dumps(summary))
raise SystemExit(0 if summary['returncode'] == 0 else 1)
