#!/usr/bin/env python3
"""Offline device DB paths; actual direct HTTP proves two previously absent keys."""
import hashlib
import json
import subprocess
from decimal import Decimal
from pathlib import Path
import integrate_20261010 as tool
from integrate_20261011_batches46_48 import item

HERE = Path(__file__).resolve().parent
PRIVATE = tool.ROOT.parent / 'worktrees/dm8-compat-20261012/private-prepay-harness'
BASE = 'work_store/apifox/2026-09-30-dm8-interface-acceptance/parallel-prepay-code-scan-20261012/'
REPORT = BASE + 'WEIGH_NEXT3_ROOT_REVIEW.md'


def verify():
    for name, digest in [
        ('weigh-next3-manifest.sha256', '88cf6a20374a777ba5712d202080f24349749d23b8df064f27c54b389a1093ac'),
        ('verify_weigh_next3.php', '5c399a8cb4cf5abed9c481ec35ec8c80f305e1073db4431973f6fa838b3bb0ba'),
        ('weigh-independent-cleanup-readback.json', 'f8cc816c84ed1bad0b98e3c24996c0d4a9c960bcb1ba78f63ad6bc9da8321ec0'),
    ]:
        assert hashlib.sha256((PRIVATE / name).read_bytes()).hexdigest() == digest
    r = json.loads(subprocess.check_output(['/opt/homebrew/opt/php@7.4/bin/php', str(PRIVATE / 'verify_weigh_next3.php')]))
    assert r['passed'] and len(r['new_http_routes']) == 3 and r['engine_http_runs'] == 10 and not r['errors']
    assert not r['real_mqtt_or_printer_called']
    read = lambda name: json.loads((PRIVATE / name).read_text())
    for lane, own in [('B', 234), ('C', 180)]:
        push = read(lane + '-weigh-push-receipt.json')
        before, after = push['before_rows']['devices'][0], push['after_rows']['devices'][0]
        history = push['after_rows']['history'][0]
        assert int(before['id']) == int(after['id']) == int(history['equipment_id']) == own
        for side in ['left', 'right']:
            assert before[side + '_dishes_uuid'] == '' and after[side + '_dishes_uuid']
            assert after[side + '_dishes_uuid'] == history[side + '_dishes_uuid']
            assert Decimal(str(after[side + '_dishes_weight'])) == Decimal(str(history[side + '_dishes_weight']))
        for stage in ['secret', 'edit']:
            e = read(lane + '-weigh-' + stage + '-receipt.json')
            assert int(e['before_row']['id']) == int(e['after_row']['id']) == own
            assert e['route'] == '/p/equipment/' + ('genSecretKey' if stage == 'secret' else 'editEquipmentByCode')
        final = read('weigh-independent-cleanup-readback.json')['mysql' if lane == 'B' else 'dm']
        assert final == {'device_id': own, 'soft_deleted': True, 'offline': True, 'code_deleted_suffix': True, 'history_rows': 1}


if __name__ == '__main__':
    audit = HERE / 'integration-20261012-batch134.json'
    assert not audit.exists()
    targets = []
    for action, line in [('pushDishes', 295), ('genSecretKey', 179), ('editEquipmentByCode', 247)]:
        spec = item('store', 'POST', '/p/equipment/' + action, BASE, evidence=REPORT,
            from_repo='unreviewed', from_source='apifox-2026-05-08',
            risk='owned-offline-device-write-MQTT-hardblocked',
            parity='partial-evidence-original-public-body-equal-or-key-redacted-and-RAM-source-matched',
            readback='tested-pass-owned-device-row-and-history-or-rotated-secret-hash-readback',
            cleanup='owned-device-softdeleted-history-retained-independent-new-connection-verified')
        if action != 'pushDishes':
            spec.update(register_new_runtime_key=True, runtime_observed_method='POST',
                        runtime_inventory_scope='controller-direct-http-observed', runtime_direct_http_proof=REPORT,
                        runtime_controller_source='application/p/controller/Equipment.php:' + str(line))
        if action == 'editEquipmentByCode':
            spec.update(mysql_state='partial-evidence-same-restaurant-update-by-only',
                        dm_state='partial-evidence-same-restaurant-update-by-only',
                        readback='partial-evidence-no-cross-restaurant-move-same-id-key-hash-and-restaurant-preserved')
        targets.append(spec)
    tool.main(targets, audit, verify)
