#!/usr/bin/env python3
"""Root one-time integration of seven catalog reads, six order reads and real XLS."""
import hashlib
import json
import os
from pathlib import Path
import subprocess
import sys
import integrate_20261010 as tool
from integrate_20261011_batches40_42 import manifest,private_files,run,sha

CAT=tool.STORE+'parallel-store-catalog-card-restaurant-read7-20261010/'
ORDER=tool.AI+'parallel-ai-order-recharge-read-20261011/'
XLS=tool.STORE+'parallel-store-meal-user-sync-export-20261011/'
PYTHON='/Users/wiscourper/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3'

def verify_catalog():
    manifest(CAT,tool.load(CAT+'MANIFEST.json'))
    r=json.loads(run(CAT,sys.executable,'verify_read7.py','private-evidence/B','private-evidence/C'))
    assert r['status']=='pass' and r['bounded_partial']==6 and r['limited_dining_zero_menus']==1
    assert r['business_http_requests']=={'B':13,'C':17} and r['root_approved_DDL']==3 and r['child_DML_DDL']==0
    for lane,pin in [('B','e86e6dfbacec57c912e1dc375757b1a54c1dfdbc0efc31e55fc115a3c1ee889f'),
                     ('C','465f64337a288bba43def0d6501fc34055e403b13323b504bb721e53796eb6b9')]:
        root=tool.ROOT/CAT/'private-evidence'/lane
        assert sha(root/'EVIDENCE_MANIFEST.json')==pin
        private_files(root,tool.load(CAT+f'private-evidence/{lane}/EVIDENCE_MANIFEST.json'))
    final=tool.load(CAT+'private-evidence/C/root-column-final.json')
    assert final['passed'] and final['old_35_column_rows_unchanged'] and final['business_DML']==0 and final['DDL_steps']==3
    assert sha(tool.ROOT.parent/'zhctproject/store/application/api/service/Card.php')==tool.load(CAT+'CARD_TDD.json')['candidate_sha256']
    assert sha(tool.ROOT.parent/'zhctproject/store/application/p/logic/Restaurant.php')==tool.load(CAT+'RESTAURANT_TDD.json')['candidate_sha256']

def verify_order():
    m=tool.load(ORDER+'manifest.json');manifest(ORDER,m['files'])
    r=json.loads(run(ORDER,sys.executable,'compare.py'))
    assert r['HTTP']==108 and r['source_original_positive_projections']==70 and r['original_HTTP_reds']==22
    assert len(r['final_full_BC_pairs'])==len(r['B_whole_body_unchanged'])==6
    sql=json.loads(run(ORDER,sys.executable,'sql_audit.py'))
    assert sql['B']=={'HTTP_business_DML':0,'DDL':0,'fixture_UPDATE':2,'fixture_INSERT':4,'SELECT':226,'metadata':180,'HTTP':54,'original_12_table_sets':648}
    assert sql['C']=={'HTTP_business_DML':0,'DDL':0,'fixture_UPDATE':2,'fixture_INSERT':4,'SELECT':142,'metadata':408,'HTTP':54,'original_12_table_sets':648}
    run(ORDER,sys.executable,'-m','unittest','discover','-p','test_compare.py')
    assert m['fixture_INSERT']=={'B':4,'C':4} and m['fixture_UPDATE']=={'B':2,'C':2}
    assert m['HTTP_business_DML']==m['DDL']==0
    req=assertions=failures=0
    for lane in ['B','C']:
        c=tool.load(ORDER+'resource-cleanup-'+lane+'.json')
        assert c['port_closed'] and c['tokens_checked_absent']==6 and c['cache_removed'] and c['own_source_removed']
        assert c['credential_collections_and_native_reports_removed'] and c['natural_recharge_counts_unchanged'] and c['base_five_tables_unchanged']
        private_files(tool.ROOT/ORDER/'private-evidence'/lane,{n:{'sha256':s}for n,s in c['private_raw_sha256'].items()})
        for relative,digest in c['source_sha256'].items():
            assert sha(tool.ROOT.parent/'zhctproject/ai_api'/relative)==digest
        for native in c['native']:
            req+=native['stats']['requests']['total'];assertions+=native['stats']['assertions']['total'];failures+=native['failures']
    assert (req,assertions,failures)==(108,432,22)

def verify_xls():
    m=tool.load(XLS+'manifest.json');root=Path(m['private_root'])
    assert str(root)=='/private/tmp/cdx-meal-sync-private.Eb1dKN' and not root.is_symlink() and root.stat().st_mode & 0o777==0o700
    for name,digest in m['private_SHA'].items():
        p=root/name
        assert not p.is_symlink() and p.stat().st_mode & 0o777==0o600 and sha(p)==digest,name
    for lane in ['B','C']:
        private_files(root/lane/'terminal',json.loads((root/lane/'terminal/manifest.json').read_text())['files'])
    replay=root/'compare-readonly.py'
    assert sha(replay)=='62fc987e512ba54e08bcfb60752171e05ed36a7ed4650805e85bb1d42ef6261e'
    env=dict(os.environ,PYTHONPATH=str(root/'parser-deps'),PYTHONDONTWRITEBYTECODE='1')
    for stage,exit_code in [('red',2),('green',0)]:
        p=subprocess.run([PYTHON,str(replay),stage],env=env,capture_output=True,text=True)
        assert p.returncode==exit_code and not p.stderr
        result=json.loads(p.stdout)
        assert result['B']['passed'] and result['B']['failure_count']==0
        assert result['C']['passed']==(stage=='green') and result['C']['failure_count']==(0 if stage=='green' else 6)
        for lane in ['B','C']:
            r=result[lane]
            assert r['cells_compared']==33 and r['biff8'] and r['sheet_shape']==[3,11] and r['summary_merge']=='A3:D3'
            assert r['source_orders']==r['source_refunds']==2 and r['whole_source_unchanged'] and r['DML']==r['DDL']==0
            assert r['list_JSON_full_body_values_shapes_order_and_native_types_match']
            if stage=='green':assert r['native_numeric_money_cells']==10
    # Read-only replay must not rewrite the sealed derived reports or raw evidence.
    for name,digest in m['private_SHA'].items():assert sha(root/name)==digest
    assert sha(tool.ROOT.parent/'zhctproject/store/application/p/logic/MealOrder.php')==m['source_root_applied_sha256']
    assert sha(tool.ROOT/XLS/'MealOrder.userListExport.patch')==m['patch_sha256']
    assert m['HTTP']['total']==11 and m['HTTP']['after_fix_C_GET']==1 and m['DML']==m['DDL']==m['new_business_data']==0
    assert m['GET_implicit_Controller_route_runtime_proven'] and not m['current_UI_click_proven']
    assert m['cleanup']['auth_config_cache_source_packages_removed'] and m['cleanup']['parent_B_10001_C_112175_preserved']

def item(repo,method,path,base,**extra):
    result=dict(repo=repo,method=method,path=path,module='数据库兼容实测',
        terminal='current-client-or-explicit-legacy-source-see-report',role='normal-private-auth-owned-or-bounded-source',
        risk='readonly-or-approved-owned-fixture-preparation',scope='customer-code-local-MySQL56-and-nonproduction-DM-only',
        evidence=base+'REPORT.md',request_type='actual-source-form-or-GET-query-see-report',
        parity='partial-evidence-complete-native-types-values-shape-and-independent-original-source',
        cleanup='source-identity-stable-marked-rows-retained-worker-auth-cache-released-private-raw-preserved')
    result.update(extra)
    return result

def batches():
    catalog=[]
    for path in ['/p/cater/search','/p/bill/dishesAll','/api/card/cardList','/api/card/logList',
                 '/p/Restaurant/restaurant_list','/p/Restaurant/restaurant_read','/p/Restaurant/mealTimeCount']:
        r=item('store','POST',path,CAT,from_repo='unreviewed',from_source='apifox-2026-05-08')
        if path.endswith('mealTimeCount'):
            r.update(mysql_state='partial-evidence-zero-menu-configuration-only',dm_state='partial-evidence-zero-menu-configuration-only',
                success_case='partial-evidence-nonempty-department-zero-count-not-dining-positive',
                parity='partial-evidence-own-source-config-totals-only-real-dining-unverified')
        catalog.append(r)
    orders=[item('ai_api','GET',f'/{app}/{path}',ORDER,
        boundary_empty_min_max='partial-evidence-owned-nonempty-cancelled-zero-money-with-images-filters-empty-auth-tenant-see-report')
        for app in ['store','terminal']for path in ['Order/list','Order/detail','user.Recharge/order']]
    export=[item('store','GET','/p/mealOrder/userListExport',XLS,
        register_new_runtime_key=True,runtime_observed_method='GET',
        runtime_client_source='public/static/src/view/reportManagement/consumeDetails/personnel.vue:11 legacy-unbound-export-url-no-current-click-claim',
        runtime_controller_source='application/p/controller/MealOrder.php:437 implicit-GET-runtime-observed',
        terminal='legacy-unbound-PC-URL-current-controller-GET-observed',
        parity='partial-evidence-actual-BIFF8-33cells-per-lane-value-type-style-merge-own-nonzero-source-not-cross-snapshot-equal')]
    return [(46,catalog,verify_catalog),(47,orders,verify_order),(48,export,verify_xls)]

if __name__=='__main__':
    plans=batches()
    for number,_,verify in plans:
        assert not Path(__file__).with_name(f'integration-20261011-batch{number}.json').exists(),'Preserve original transition audit'
        verify()
    for number,items,verify in plans:
        tool.main(items,Path(__file__).with_name(f'integration-20261011-batch{number}.json'),verify)
