#!/usr/bin/env python3
"""Integrate finished hardware, client settings and read-only billing evidence.

Counts are scenario-partial only. Preserve unrelated concurrent-data unknowns,
shared GET input limitations, SQL lexical warnings and all open coverage gates.
"""
import hashlib
import json
from pathlib import Path
import subprocess
import sys
import integrate_20261010 as tool

HARD=tool.STORE+'parallel-store-hardware-correction-owned-20261010/'
CLIENT=tool.AI+'parallel-ai-client-settings-20261010/'
BILL=tool.STORE+'parallel-store-billing-get-readonly-20261010/'

def run(relative,*args):
    return subprocess.run([sys.executable,str(tool.ROOT/relative),*args],check=True,capture_output=True,text=True)

def sha(relative,expected):
    assert hashlib.sha256((tool.ROOT.parent/relative).read_bytes()).hexdigest()==expected

def verify_hardware():
    base=tool.ROOT/HARD
    paths=[str(base/'evidence/B'),str(base/'evidence/C')]
    result=json.loads(run(HARD+'verify.py',*paths).stdout)
    assert result['status']=='pass' and result['paired_positive_cases']==7
    assert not result['full_natural_database_unchanged_claimed'] and not result['sql_fingerprint_gate_closed']
    run(HARD+'test_verify.py',*paths)
    for line in (base/'SOURCE_SHA256.txt').read_text().splitlines():
        if not line:continue
        expected,path=line.split(None,1)
        sha('zhctproject/store/'+path,expected)

def verify_client():
    result=json.loads(run(CLIENT+'compare.py').stdout)
    assert result['actual_available_wire_pairs']==40 and result['strict_positive_pairs']==38
    assert len(result['new_positive_methods'])==8 and result['initial_two_B_raw_lost_and_explicitly_not_counted'] is True
    run(CLIENT+'test_compare.py');run(CLIENT+'compare_cli.py');run(CLIENT+'test_compare_cli.py')
    sha('zhctproject/ai_api/app/common/database/DmBuilder.php','58e1e79ce69881cc305c6fd33adec0e9a3d030ac15b4c00ae464cbaa4cce2b59')
    for lane in ['B','C']:
        r=tool.load(CLIENT+'resource-cleanup-'+lane+'.json')
        assert r['own_worker_listening'] is False and r['private_cache_files']==0
        assert r['ephemeral_token_files_absent'] and r['raw_token_bearing_CLI_reports_removed_after_sanitized_SHA_archival']
        assert r['retained_business_rows_untouched']

def verify_billing():
    result=json.loads(run(BILL+'compare.py').stdout)
    assert result['passed'] is True and len(result['checks'])==18 and all(result['checks'].values())
    sha('zhctproject/store/application/p/logic/BillingRecord.php','28403f3c1cfc8088f05497fc108f1755b7391b1a4abb764bb443bbb86f00f39c')
    r=tool.load(BILL+'resource-cleanup.json')
    for lane in ['B','C']:
        assert r[lane]['private_worker_absent'] and r[lane]['private_port_closed'] and r[lane]['runtime_removed']
    assert r['tokens_raw_responses_natural_rows_cli_reports_cache_and_copied_configs_removed']
    assert r['natural_rows_deleted_or_rolled_back']==0 and r['natural_billing_tables_unchanged'] is True
    assert r['broad_identity_consumption_and_background_gates']=='unknown'

def target(repo,method,path,evidence,scope,**extra):
    return dict(repo=repo,method=method,path=path,module='数据库兼容有界验收',terminal='PC-or-terminal-see-report',
        role='approved-private-normal-auth-context',risk='read-or-owned-config-write-see-report',scope=scope,
        evidence=evidence+'REPORT.md',**extra)

def specs():
    hard=[target('store','POST',path,HARD,'store-primary-owned-seven-table-consumed-relations-global-background-unknown',
        parity='partial-evidence-seven-nonempty-strict-JSON-pairs-only-source-owned-image-PK-mapped',
        readback='tested-pass-complete-owned-chain-and-actual-consumed-window-global-natural-unchanged-not-proven',
        request_type='current-controller-form-owned-date-staff-department',
        cleanup='retained-seven-hidden-marked-rows-each-own-menu4-1-4-restored-workers-state-cache-token-released',
        boundary_empty_min_max='partial-evidence-type1-quote-Chinese-search-fallback-and-Boolean-flag-not-all-hardware-branches')
        for path in ['/p/date_menu/hardwareInfo','/p/dateMenu/checkMenuList']]
    client=[target('ai_api','GET' if action=='detail' else 'POST',f'/{module}/client.{kind}.Setting/{action}',CLIENT,
        'ai-primary-only-owned-h5-wxapp-composite-keys-private-cache-no-SDK-external-or-permission-write',
        parity='partial-evidence-40-strict-wire-pairs-plus-six-native-CLI-read-pairs-DM-VALUES-identifier-fixed',
        request_type='GET-query' if action=='detail' else 'current-PC-JSON-form',
        boundary_empty_min_max='partial-evidence-JSON-Boolean-Chinese-quote-allowlist-partial-merge-array-replace-and-invalid-key',
        cleanup='retained-H5two-WXfour-exact-composite-rows-disabled-natural-full-SHA-unchanged-private-resources-released')
        for module in ['store','terminal'] for kind in ['h5','wxapp'] for action in ['detail','update']]
    billing=[]
    for method,actions in [('GET',['list','lists','statistics','export','detail','logs']),('POST',['detail','logs','export','statistics'])]:
        for action in actions:
            x=target('store',method,'/p/billingrecord/'+action,BILL,
                'store-primary-readonly-billing-three-tables-broad-identity-background-unknown',
                parity='partial-evidence-complete-per-engine-natural-original-projection-and-MySQL-wire-unchanged-not-natural-value-cross-mapping',
                request_type='standard-GET-query-no-body' if method=='GET' else 'current-PC-form',
                cleanup='read-only-three-original-tables-and-metadata-unchanged-private-resources-and-SSH-master-released',
                boundary_empty_min_max='partial-evidence-original-empty-export-statistics-and-missing-bill-refusal-valid-time-sentinel-logs-see-report')
            if method=='GET' and action in ['detail','logs']:
                x.update(mysql_state='partial-evidence-shared-original-GET-query-not-consumed',
                    dm_state='partial-evidence-shared-original-GET-query-not-consumed',
                    success_case='partial-evidence-shared-GET-rejection-only-no-positive-GET-detail-or-log',
                    mysql_readback='partial-evidence-source-table-unchanged-common-string2-bill-not-found',
                    dm_readback='partial-evidence-source-table-unchanged-common-string2-bill-not-found',
                    parity='partial-evidence-shared-original-rejection-not-positive-no-artificial-GET-body')
            billing.append(x)
    return [(28,hard,verify_hardware),(29,client,verify_client),(30,billing,verify_billing)]

if __name__=='__main__':
    batches=specs()
    for n,_,verify in batches:
        assert not Path(__file__).with_name(f'integration-20261010-batch{n}.json').exists(), 'Do not overwrite original transition audit'
        verify()
    for n,items,verify in batches:
        tool.main(items,Path(__file__).with_name(f'integration-20261010-batch{n}.json'),verify)
