#!/usr/bin/env python3
"""Root intake: three original sports-write endpoints, not full-domain closure."""
import hashlib
import json
import re
import subprocess
import sys
from pathlib import Path
import integrate_20261010 as tool
from integrate_20261011_batches46_48 import item
from integrate_20261013_batches221_223_224_226 import shape

HERE = Path(__file__).resolve().parent
ROOT = Path('/Users/wiscourper/Documents/workspace/local/dm8-independent-20261013/session-ai-exercise')
REPORT = tool.AI + 'parallel-s2-sports-records-20261013/ROOT_REVIEW.md'
ACTIONS = {332: 'running', 333: 'strength', 334: 'bicycle'}


def verify():
    for name, sha in {
        'REPORT.md': 'd7a5d6237249131920650d3ea9d7aa596bf6f096c49671de5780d5f071c3cd3f',
        'verify.py': 'aa6cd94027462b4adbe4c7d924e0eb1ace2dbc43b9c9c780229423807df256a1',
        'manifest.json': '9193a5034f9fabcf84a9d51fb3dfcd33b7d61ba0ba7ae400e7e4323d6ef2f122',
    }.items():
        assert hashlib.sha256((ROOT / name).read_bytes()).hexdigest() == sha, name
    result = json.loads(subprocess.check_output([sys.executable, '-B', str(ROOT / 'verify.py')]))
    assert result['checks'] == 854 and result['positive_routes'] == 3
    bodies = {}
    for lane in ('B', 'C'):
        side = ROOT / ('evidence-' + lane)
        pins = json.loads((side / 'source-pins.json').read_text())
        for name, sha in pins.items():
            source = subprocess.check_output(['git', '-C', str(tool.source_root('ai_api')),
                'show', '684fd60374ee22228c70cf3c7d2ec8fa3998b0f6:' + name])
            assert hashlib.sha256(source).hexdigest() == sha, name
        for batch, action in ACTIONS.items():
            events = json.loads((side / f'run{batch}-{lane}.json').read_text())
            intent = next(e for e in events if 'intent' in e)
            http = next(e for e in events if 'raw' in e)
            assert intent['method'] == 'POST' and intent['path'] == '/api/yingjiduo.record/' + action
            assert type(http['raw']) is str and 0 < len(http['raw'].encode()) <= 1048576
            assert re.fullmatch(r'HTTP/1\.[01] 200 OK', http['headers'][0])
            assert any(h.lower().startswith('content-type:application/json') for h in http['headers'])
            body = json.loads(http['raw'])
            assert body == http['json'] and shape(body) == shape(http['json'])
            assert type(body['data']) is dict and type(body['data']['session_id']) is int
            assert body['data']['session_id'] == http['audit']['sid']
            assert http['audit']['source'] == pins
            assert http['audit']['writes'] == 5 and http['audit']['tx'] == ['begin', 'commit']
            body['data']['session_id'] = '<verified-owned-generated-id>'
            if lane == 'B':
                bodies[batch] = body
            else:
                assert body == bodies[batch] and shape(body) == shape(bodies[batch])
        failures = json.loads((side / f'run335-{lane}.json').read_text())
        for event in failures:
            if 'raw' in event:
                decoded = json.loads(event['raw'])
                assert decoded == event['json'] and shape(decoded) == shape(event['json'])


if __name__ == '__main__':
    audit = HERE / 'integration-20261013-s2-332-335.json'
    assert not audit.exists(), 'Never replay integration main'
    rows = [item('ai_api', 'POST', '/api/yingjiduo.record/' + action, '', evidence=REPORT,
        terminal='运动设备上报API', role='original-merchant-client-validation-explicit-owned-user-id',
        scope='AI-owned-user-read-and-customer-Store-sports-three-table-transaction',
        request_type='application/x-www-form-urlencoded',
        success_case='partial-evidence-original-owned-session-raw-three-metric-inserts-with-commit',
        readback='tested-pass-full-owned-source-rows-native-types-raw-payload-and-five-real-inserts',
        parity='partial-evidence-full-native-HTTP-JSON-only-generated-session-id-diff',
        boundary_empty_min_max='partial-evidence-missing-device-and-not-logged-in-no-write',
        cleanup='marked-sports-rows-retained-worker-token-released-no-real-device-or-SDK')
        for action in ACTIONS.values()]
    tool.main(rows, audit, verify)
