#!/usr/bin/env python3
"""Finished independent Express, Category, Delivery evidence; batch23 is separate."""
from pathlib import Path
import subprocess
import sys
import integrate_20261010 as tool

EXP=tool.AI+'parallel-ai-express-owned-crud-20261010/'
CAT=tool.STORE+'parallel-store-custom-category-write-20261010/'
DEL=tool.AI+'parallel-ai-terminal-delivery-crud-20261010/'

def run(relative):subprocess.run([sys.executable,str(tool.ROOT/relative)],check=True,capture_output=True)
def verify_exp():
    run(EXP+'compare.py');run(EXP+'test_compare.py')
    r=tool.load(EXP+'resource-cleanup.json')
    assert r['B_worker_stopped'] and r['C_worker_stopped'] and r['B_tokens_absent'] and r['C_tokens_absent']
    assert r['B_18321_listeners']==r['C_18322_listeners']==r['cache_files_each']==0
    assert r['actual_formal_delete_successes_each_engine']==0 and r['failed_delete_original_rows_unchanged']

def verify_cat():
    run(CAT+'compare.py')
    import hashlib
    source=tool.ROOT.parent/'zhctproject/store/application/p/logic/DishCustomCategory.php'
    assert hashlib.sha256(source.read_bytes()).hexdigest()=='9f911082ad747d25f7d23c9598a0b2d785522ba40cd6a93298f050e87c79666f'

def verify_del():
    run(DEL+'compare.py');run(DEL+'test_compare.py')
    r=tool.load(DEL+'resource-cleanup.json')
    assert r['B_worker_stopped'] and r['C_worker_stopped'] and r['B_token_absent'] and r['C_token_absent']
    assert r['B_port_18321_listeners']==r['C_port_18322_listeners']==r['cache_files_each']==0
    assert r['goods_or_order_or_finance_or_permission_writes']==r['real_external_calls']==0

def common(repo,method,path,evidence,module,scope,**extra):
    return dict(repo=repo,method=method,path=path,evidence=evidence+'REPORT.md',module=module,scope=scope,
        terminal='PC-or-terminal-see-report',role='private-approved-synthetic-owned-context',risk='config-write-or-read-see-report',
        cleanup=extra.pop('cleanup','marked-owned-business-data-retained-private-token-cache-workers-reclaimed'),**extra)

def specs():
    express=[]
    for app in ['store','terminal']:
        for action in ['list','all','add','edit','delete']:
            x=common('ai_api','GET' if action in ['list','all'] else 'POST',f'/{app}/setting.Express/{action}',EXP,
                '物流公司配置','ai-primary-own-express-order-reference-count-only-no-shipping',
                parity='partial-evidence-24-positive-full-wire-source-pairs-UNIX-epoch-and-leading-zero-codes',
                request_type='GET-query' if action in ['list','all'] else 'current-PC-JSON-form-and-expressId')
            if action=='delete':
                x.update(mysql_state='tested-fail-shared-original-order-express_id-missing',dm_state='tested-fail-shared-original-order-express_id-missing',
                    success_case='tested-fail-shared-original-reference-schema-not-positive',
                    mysql_readback='tested-fail-original-row-unchanged-no-delete',dm_readback='tested-fail-original-row-unchanged-no-delete',
                    readback='tested-fail-original-order-column-absent-both-engines-original-express-row-unchanged',
                    parity='tested-fail-shared-original-business-reference-error-no-fabricated-column')
            express.append(x)
    category=[common('store','POST','/p/dishCustomCategory/'+a,CAT,'自定义菜品分类',
        'store-primary-only-owned-category-no-dishes-person-permission-write',request_type='current-PC-form',
        parity='partial-evidence-22-original-and-six-owned-regression-source-verified-main-list-date-normalized',
        boundary_empty_min_max='partial-evidence-default-enabled-immediate-disable-name-boundaries-NULL-code-own-options-and-zero-references',
        duplicate_retry='partial-evidence-duplicate-name-rejected-repeat-edit-and-repeat-delete-source-unchanged',
        cleanup='retained-one-disabled-softdeleted-marked-category-each-natural-dishes-category-projection-unchanged-resources-released')
        for a in ['add','update','changeStatus','delete','list','options']]
    delivery=[common('ai_api','GET' if a in ['list','all','detail'] else 'POST','/terminal/setting.Delivery/'+a,DEL,
        '终端配送模板配置','ai-primary-own-delivery-rule-goods-reference-count-only-no-shipping-or-order-write',
        parity='partial-evidence-18-full-wire-source-pairs-JSON-CLOB-double-fee-scale-UNIX-window-and-parent-child-ownership',
        request_type='GET-query' if a in ['list','all','detail'] else 'current-PC-homologous-JSON-form-deliveryId',
        boundary_empty_min_max='partial-evidence-two-templates-multiple-rules-physical-rule-replace-empty-rules-refusal-and-parent-soft-delete')
        for a in ['list','all','detail','add','edit','delete']]
    return [(21,express,verify_exp),(22,category,verify_cat),(24,delivery,verify_del)]

if __name__=='__main__':
    batches=specs()
    for _,_,verify in batches:verify()
    for n,items,verify in batches:
        audit=Path(__file__).with_name(f'integration-20261010-batch{n}.json')
        if audit.exists():raise RuntimeError('Original transition audit exists; do not rerun '+str(n))
        tool.main(items,audit,verify)
