#!/usr/bin/env python3
"""Recompute scratch equivalence from actual private originals, without DB access."""
import hashlib
import json
import re
from pathlib import Path

root = Path(__file__).parent
private = root / 'scratch-private-evidence'
plan_file = root / 'scratch-executed-v2.json'
assert hashlib.sha256(plan_file.read_bytes()).hexdigest() == '2e4257689999d7d77bc58ce6858c7ae32a9a45df7488b7217c72bd009fd62a7a'
plan = json.loads(plan_file.read_text())
def read(path):
    return json.loads(path.read_text())
def seconds(value):
    match = re.fullmatch(r'(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d)(?:\.0{1,6})?', value)
    assert match, 'Nonzero precision must not be discarded'
    return match.group(1)
summary = {'passed': True, 'HTTP': 0, 'DML': 0, 'DDL': 0, 'SELECT': {}, 'cases': [], 'scratch_objects_remaining': 0, 'business_source_exact': True}
outputs = {}
for lane in ('B', 'C'):
    directory = private / lane
    baseline = read(directory / 'business-baseline.json')
    assert read(directory / 'business-final.json') == baseline
    assert read(directory / 'collision-before.json') == {'table': [], 'trigger': []}
    assert read(directory / 'collision-after.json') == {'table': [], 'trigger': []}
    journal = read(directory / 'journal.json')
    assert all(entry['ok'] is True for entry in journal)
    assert len([entry for entry in journal if entry['kind'] == 'DML']) == 29
    assert len([entry for entry in journal if entry['kind'] == 'DDL']) == (2 if lane == 'B' else 4)
    recorded = read(directory / 'summary.json')
    assert recorded['DML'] == 29 and recorded['SELECT'] <= 120 and recorded['cleanup_complete']
    spec = plan['lanes'][lane]
    allowed = [spec['create_table'], spec['seed_SQL']] + ([spec['create_trigger']] if lane == 'C' else []) + spec['cleanup']
    for case in spec['cases']:
        allowed.extend([case['reset_SQL'], case['test_SQL']])
    assert sorted(entry['SQL'] for entry in journal) == sorted(allowed), 'Only exact approved SQL, including exact cleanup'
    actual_cases = {}
    for case in spec['cases']:
        label = case['label']
        reset, test = read(directory / (label + '.reset.json')), read(directory / (label + '.test.json'))
        assert reset['SQL'] == case['reset_SQL'] and test['SQL'] == case['test_SQL']
        for evidence in (reset, test):
            assert len(evidence['own_after']['rows']) == 1
            assert evidence['business_after'] == {table: baseline[table] for table in ('nutrition_category', 'material_category')}
        before, after = reset['own_after']['rows'][0], test['own_after']['rows'][0]
        for key, expected in case['reset_expected'].items():
            assert (seconds(before[key]) if key == 'update_time' else str(before[key])) == expected
        for key, expected in case['test_expected_non_time'].items():
            assert str(after[key]) == expected
        assert hashlib.sha256(after['name'].encode()).hexdigest() == test['name_utf8_sha256']
        assert len(after['name'].encode()) == test['name_bytes']
        timestamp = seconds(after['update_time'])
        effect = 'old' if timestamp == case['old'] else ('explicit' if timestamp == case['explicit'] else ('clock' if seconds(reset['own_after']['clock']) <= timestamp <= seconds(test['own_after']['clock']) else 'other'))
        assert effect == test['effect'] == case['expected_timestamp_hypothesis']
        actual_cases[label] = {'effect': effect, 'name_bytes': test['name_bytes'], 'name_sha256': test['name_utf8_sha256'], 'rowCount': test['rowCount'], 'non_time': {key: str(after[key]) for key in ('id', 'name', 'flag')}}
    outputs[lane] = actual_cases
    summary['DML'] += recorded['DML']
    summary['DDL'] += recorded['DDL']
    summary['SELECT'][lane] = recorded['SELECT']
for label in outputs['B']:
    b, c = outputs['B'][label], outputs['C'][label]
    assert {key: value for key, value in b.items() if key != 'rowCount'} == {key: value for key, value in c.items() if key != 'rowCount'}
    summary['cases'].append({'label': label, 'effect': b['effect'], 'name_bytes': b['name_bytes'], 'B_rowCount': b['rowCount'], 'C_rowCount': c['rowCount'], 'storage_equal': True})
assert summary['DML'] == 58 and summary['DDL'] == 6 and len(summary['cases']) == 14
print(json.dumps(summary, ensure_ascii=False, indent=2))
