#!/usr/bin/env python3
import json
from pathlib import Path


def exact(a, b, path='$'):
    if type(a) is not type(b): raise AssertionError(f'type mismatch {path}')
    if isinstance(a, dict):
        if set(a) != set(b): raise AssertionError(f'keys mismatch {path}')
        for key in a: exact(a[key], b[key], f'{path}.{key}')
    elif isinstance(a, list):
        if len(a) != len(b): raise AssertionError(f'length mismatch {path}')
        for index, values in enumerate(zip(a, b)): exact(*values, f'{path}[{index}]')
    elif a != b: raise AssertionError(f'value mismatch {path}')


def validate(lane):
    assert lane['error'] is None and len(lane['cases']) == 38 and len(lane['original_proofs']) == 14
    assert len({(c['method'], c['path']) for c in lane['cases']}) == 10
    for c in lane['cases']:
        assert c['http_status'] == 200 and c['body']['status'] == 200 and c['trace_format_valid'] is True
    for p in lane['original_proofs']:
        assert p['all_original_fields_verified'] is True and p['owned_id_store_verified'] is True
        assert isinstance(p['values']['phone'], str) and p['values']['phone'].startswith('000')
    assert len(lane['write_audit']) == 14
    for event in lane['write_audit']:
        assert event['table'] == 'yoshop_store_address' and event['owned_scope_verified'] is True
    proof = lane['region_cache_proof']
    assert proof['original_all_rows'] == 3835 and proof['full_original_projection_equal'] is True
    assert proof['counts_equal'] is True and proof['shared_cache_accessed'] is False
    clean = lane['cleanup']
    assert clean['fresh_pdo_owned_rows'] == 0 and clean['tokens_absent'] is True
    assert clean['private_region_cache_absent'] is True and clean['private_cache_files'] == 0
    assert clean['address_and_region_full_sha_unchanged'] is True
    assert all(d['owned_positive_id_store_exact_name'] for d in clean['exact_delete_scopes'])
    assert clean['same_named_user_address_primary_keys_not_treated_as_references'] is True


def compare(b, c):
    validate(b); validate(c)
    for key in ('cases', 'original_proofs', 'loaded_boundary', 'region_cache_proof', 'write_audit'):
        exact(b[key], c[key], key)
    return {'http_pairs': 38, 'actual_methods': sorted({f"{r['method']} {r['path']}" for r in b['cases']}),
            'successful_writes': 14, 'nonempty_reads': 20, 'empty_sequence_boundaries': 4,
            'independent_original_pairs': 14, 'complete_wire_type_value_order_differences': 0,
            'simultaneous_two_tenant_phone_OR_scope_verified': True,
            'region_all_3835_rows_and_counts_verified_against_original': True,
            'business_code_changed': False}


if __name__ == '__main__':
    base = Path(__file__).parent
    print(json.dumps(compare(json.loads((base / 'evidence-B.json').read_text()),
                             json.loads((base / 'evidence-C.json').read_text())), indent=2))
