#!/usr/bin/env python3
"""Nine AI DB reads, shared missing-method diagnostic and a no-DB enum."""
import csv
import importlib
from pathlib import Path
import sys
import integrate_20261010 as tool
from integrate_20261011_batches40_42 import private_files, run, sha
from integrate_20261011_batches46_48 import item

BASE = tool.AI + 'parallel-ai-remaining-read12-20261011/'
PIN = '678bed9a6da025df976d6d1c9604a6634e3fb5fe2f82a56b50df8573212d4393'

def verify():
    root = tool.ROOT / BASE
    assert sha(root / 'manifest.json') == PIN
    m = tool.load(BASE + 'manifest.json')
    assert len(m['public']) == 68 and len(m['private']) == 233
    for r in m['public'] + m['private']:
        p = Path(r['path'])
        assert not p.is_absolute() and '..' not in p.parts
        f = root / p
        assert f.is_file() and not f.is_symlink() and f.stat().st_size == r['bytes'] and sha(f) == r['sha256']
    assert all(r['path'].startswith('private-evidence/') for r in m['private'])
    private_files(root / 'private-evidence', {r['path'][len('private-evidence/'):]: r for r in m['private']})
    sys.path.insert(0, str(root))
    try:
        verifier = importlib.import_module('verify_final')
        r = verifier.verify_all()
        assert r['true_HTTP'] == r['complete_wire'] == 60
        assert r['B_old_raw_trace_only_equal'] == 4 and r['strict_effective_BC_pairs'] == 26
        assert r['new_preparation_INSERT_each'] == 13 and r['HTTP_DML'] == r['HTTP_DDL'] == 0
        assert sum(bool(c['differences']) for c in r['original']['B']) == 0
        assert sum(bool(c['differences']) for c in r['original']['C']) == 4
        assert all(not c['differences'] for lane in r['final'].values() for c in lane)
        audit = importlib.import_module('sql_audit').all_audits()
        for lane, phase, count, selects in [('B', 'original', 99, 52), ('C', 'original', 189, 52),
                                            ('B', 'final', 27, 13), ('C', 'final', 51, 13)]:
            a = audit[lane][phase]
            assert a['framework_plans'] == a['actual_prepare'] == a['actual_execute'] == count
            assert a['HTTP_business_SELECT'] == selects and a['Auth_preparation_business_SELECT'] == 2
            assert a['DML'] == a['DDL'] == 0
    finally:
        sys.path.pop(0)
        for name in ['verify_final', 'compare', 'sql_audit']:
            sys.modules.pop(name, None)
    run(BASE, sys.executable, '-m', 'unittest', 'test_compare.py', 'test_sql_audit.py', 'test_verify_final.py')
    pins = tool.load(BASE + 'source-final-sha.json')
    assert len(pins['files']) == 6168 and len(pins['accepted_changes']) == 2
    for relative, digest in pins['files'].items():
        assert sha(tool.ROOT.parent / 'zhctproject/ai_api' / relative) == digest, relative
    img = tool.load(BASE + 'private-evidence/C/img-ddl-journal.json')
    assert img['success'] and len(img['statements']) == 2 and all(s['sent'] and s['returned'] for s in img['statements'])
    assert img['before_projection'] == img['after_projection'] == {
        'rows': 1775, 'sha256': '1fd0eef856df45a66f6c2f34c11022d9e8a65c960df641edcdf0a583ec5ff2a3'}
    assert img['before_metadata'] == img['after_metadata'][:20] and img['before_objects'] == img['after_objects']
    assert img['after_metadata'][20]['column_name'] == 'IMG'
    for lane in 'BC':
        c = tool.load(BASE + f'resource-cleanup-{lane}.json')
        assert c['final42_full_rows_exact'] and c['retained13_full_rows_exact'] and c['final179_enum_unchanged']
        assert c['all6168_final_source_pins_verified'] and c['all_Auth_cache_files_absent']
        assert all(worker['absent'] for worker in c['own_original_final_workers'].values())
        assert c['HTTP'] == c['DML'] == c['DDL'] == 0
        if lane == 'C':
            assert all(value is True for key, value in c['IMG_final'].items() if key != 'original1775_full20_sha256')
    for r in m['public'] + m['private']:
        assert sha(root / r['path']) == r['sha256']

def targets():
    rows = list(csv.DictReader((tool.ROOT / BASE / 'interface-ledger.csv').open()))
    assert len(rows) == 11
    out = []
    for r in rows:
        t = item('ai_api', 'POST', r['path'], BASE,
            risk='readonly-owned-staff-survey-and-native-dictionary-no-formal-writes',
            request_type='application/json-original-post-body',
            parity='partial-complete-DTO-26-effective-BC-pairs-and-four-MySQL-raw-trace-only-controls',
            boundary_empty_min_max='partial-owned-query-empty-date-type-missing-and-tenant-boundaries-see-report')
        if r['status'] == 'shared_source_failure':
            t.update(scope='shared-original-missing-getTrainDates-no-positive-business-DB',
                mysql_state='tested-fail-shared-original-undefined-getTrainDates',
                dm_state='tested-fail-shared-original-undefined-getTrainDates',
                success_case='tested-fail-shared-original-undefined-method-not-DM-regression',
                readback='not-applicable', mysql_readback='not-applicable', dm_readback='not-applicable',
                parity='tested-pass-same-original-error-envelope-not-positive-business-result')
        elif r['status'] == 'no_database_static_enum':
            t.update(scope='no-db', readback='not-applicable', mysql_readback='not-applicable', dm_readback='not-applicable',
                success_case='tested-pass-original-complete-nine-static-Unit-enum-no-business-DB',
                parity='tested-pass-static-enum-values-types-and-order-not-database-coverage')
        else:
            assert r['status'] == 'dual_business_partial'
            if r['path'].endswith('/nutrition.Nutrition/detail'):
                t['boundary_empty_min_max'] = 'partial-nonempty-original-null-recommend-energy-empty-date-common-missing-MealRecommend-error-remains'
            if '/store.Staff/' in r['path']:
                t['terminal'] = 'legacy-source-POST-observed-no-current-UI-direct-caller-proof'
        out.append(t)
    return out

if __name__ == '__main__':
    audit = Path(__file__).with_name('integration-20261011-batch67.json')
    assert not audit.exists(), 'Preserve original transition audit'
    tool.main(targets(), audit, verify)
