#!/usr/bin/env python3
"""Strict HTTP/independent physical-value comparison; no broad field ignores."""
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, pair in enumerate(zip(a, b)):
            exact(*pair, f'{path}[{index}]')
    elif a != b:
        raise AssertionError(f'value mismatch {path}')


def validate(lane):
    assert lane['error'] is None
    assert len(lane['cases']) == 12 and len(lane['jobs']) == 9 and len(lane['proofs']) == 21
    assert len(lane['robot_captures']) == 9 and lane['real_queue_executed'] is False
    for case in lane['cases']:
        assert case['http_status'] == 200 and case['body']['status'] == 200
        assert case['trace_format_valid'] is True and case['method'] == 'POST'
    for proof in lane['proofs']:
        assert proof['all_original_fields_independently_equal'] is True
        assert proof['earlier_history_original_rows_unchanged'] is True
        assert proof['current_rows'] == 1 and proof['values']['staff_id'] == 1
        assert proof['values']['store_id'] == 2147000621
    for event in lane['write_audit']:
        assert event['owned_scope_verified'] is True
        assert event['table'] in ('yoshop_meal_recommend', 'yoshop_meal_recommend_history')
    clean = lane['fresh_pdo_cleanup']
    assert not any(clean['fresh_pdo_owned_rows'].values())
    for key in ('token_absent', 'five_input_tables_and_dictionaries_full_sha_unchanged',
                'large_output_counts_restored', 'framework_dml_all_owned'):
        assert clean[key] is True
    assert clean['large_output_full_sha_performed'] is False
    assert clean['large_output_before_counts'] == clean['large_output_after_counts']


def compare(b, c):
    validate(b)
    validate(c)
    for key in ('cases', 'jobs', 'proofs', 'robot_captures', 'fixture_audit'):
        exact(b[key], c[key], key)
    # MySQL INSERT SET vs DM INSERT VALUES are intentionally distinct SQL forms;
    # both must have explicit owned inserted values. UPDATE is owned-PK scoped.
    project = lambda lane: [{key: event[key] for key in ('operation', 'table', 'owned_scope_verified')}
                            for event in lane['write_audit']]
    exact(project(b), project(c), 'write_audit')
    return {'http_pairs': len(b['cases']), 'actual_post_methods': sorted({case['path'] for case in b['cases']}),
            'job_pairs_not_http': len(b['jobs']), 'independent_output_pairs': len(b['proofs']),
            'strict_http_and_owned_output_differences': 0, 'complete_wire_type_shape_preserved': True,
            'large_output_full_table_sha_claimed': 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))
