#!/usr/bin/env python3
"""Strengthen existing meal read evidence after scoped original calculation."""
import hashlib
import json
import subprocess
from pathlib import Path
import integrate_20261010 as tool
from integrate_20261011_batches46_48 import item
from integrate_20261012_batch148 import shape

HERE = Path(__file__).resolve().parent
PRIVATE = Path('/private/tmp/cdx-ai-hk-course-b.Kmdirn')
BASE = 'work_ai_api/2026-09-30-dm8-interface-acceptance/parallel-meal-calculation-full-dto-20261012/'


def verify():
    file = PRIVATE / 'meal157-source-only/MANIFEST_157.json'
    assert hashlib.sha256(file.read_bytes()).hexdigest() == 'e9ac3dadf667c133acbbde2e4c554b786d678c398f7117601b6ed9d88377bb04'
    manifest = json.loads(file.read_text())
    for path, digest in manifest['assets_sha256'].items():
        assert '..' not in Path(path).parts
        assert hashlib.sha256((PRIVATE / path).read_bytes()).hexdigest() == digest
    for path, digest in manifest['business_source_sha256'].items():
        assert hashlib.sha256((tool.source_root('ai_api') / path).read_bytes()).hexdigest() == digest
    for script, status in [('verify_meal157_original_red.php', 'verified_original_consumer_scoped_write_and_full_dto_red'),
                            ('verify_meal157_fixed46.php', 'verified_full46_fixed2_B_C_contract')]:
        result = json.loads(subprocess.check_output(['/opt/homebrew/opt/php@7.4/bin/php',
            str(PRIVATE / 'meal157-source-only' / script)]))
        assert result['status'] == status
    cases = [
        ('B', 'runtime/meal157-postcalc-read-6a46b514c7b84c67124065c62c7537cd201264e355ce09e6476793ee73a329de.json',
         'runtime/meal157-fixed46-get-f6aedb64563e568bd2f14b13ab929e47d1ebb799e95c5091870d79481b02c1bc.json',
         'runtime/meal157-all46-metadata-88fba2db9ead3b911fa71dc8119096d18a172a8f45d47254e919b758dfe961a8.json'),
        ('C', 'meal157-source-only/C_meal157_postcalc_read.json', 'meal157-source-only/C_meal157_fixed46_get.json',
         'meal157-source-only/C_meal157_all46_metadata.json'),
    ]
    normalized = {}
    for lane, oldfile, newfile, metafile in cases:
        events = lambda path: {x['phase']: x for x in json.loads((PRIVATE / path).read_text())['events']}
        old, new = events(oldfile), events(newfile)
        fields = json.loads((PRIVATE / metafile).read_text())['metadata']
        assert len(fields) == 46
        for slot in ['today', 'future']:
            before = json.loads(old['after_http_' + slot]['raw_response_exact'])
            after = json.loads(new['after_http_' + slot]['raw_response_exact'])
            before.pop('trace_id', None)
            after.pop('trace_id', None)
            def children(body):
                return [row for group in body['data']['list'] for category in group['data'] for row in category['dishes']]
            prior_rows, rows = children(before), children(after)
            assert len(rows) == len(prior_rows) == 1
            if lane == 'C':
                for name in fields:
                    assert type(prior_rows[0][name]) in (int, float)
                    prior_rows[0][name] = format(prior_rows[0][name], '.2f')
            assert before == after and shape(before) == shape(after)
            for name in ['id', 'meal_id', 'staff_id', 'meal_time', 'create_by', 'create_time', 'update_time']:
                rows[0].pop(name)
            normalized[lane, slot] = after
    for slot in ['today', 'future']:
        assert normalized['B', slot] == normalized['C', slot]
        assert shape(normalized['B', slot]) == shape(normalized['C', slot])


if __name__ == '__main__':
    audit = HERE / 'integration-20261012-batch157.json'
    assert not audit.exists()
    # Existing key only: improve the previously unverified nested DTO and async
    # calculation branch, without claiming new HTTP or full queue-command keys.
    specs = [item('ai_api', 'GET', '/store/meal.Meals/MealsInfo', BASE,
        risk='owned-original-ENUM2-calculation-private-Qw-stub-no-real-queue-no-recommendation-write',
        readback='tested-pass-owned-calculated-meal-infos-all46-values-source-linked-get-all-rows-unchanged',
        success_case='partial-evidence-two-owned-dates-one-dish-no-recommendation-consumer-branch',
        parity='partial-evidence-entire-JSON-types-and-nonidentity-values-match-all46-DECIMAL-fields',
        cleanup='existing-owned-calculated-rows-retained-no-new-row-inserts-private-Qw4-real-external0-tokens-absent')]
    tool.main(specs, audit, verify)
