"""Check the T684 display repair and preservation of its entries.

Run with SageMath and the two API snapshots beside this file:
    sage -pip install numberdb
    sage -python repair_check.py before.json after.json

The default snapshot names are before.json and after.json. This checks exact
stored-interval arithmetic and unchanged values, not a new computation of the
Petersson integrals or an independent argument-selection verdict.
"""
import hashlib
import json
from decimal import Decimal
from fractions import Fraction
from pathlib import Path
import sys
import numberdb.sage as numberdb
from sage.rings.integer_ring import ZZ
from sage.rings.rational_field import QQ
from sage.version import version as sage_version

base = Path(__file__).resolve().parent
before_path = Path(sys.argv[1]) if len(sys.argv)>1 else base/'before.json'
after_path = Path(sys.argv[2]) if len(sys.argv)>2 else base/'after.json'
before = json.loads(before_path.read_text())
after = json.loads(after_path.read_text())
expected = json.loads(json.dumps(before))
expected['Parameters']['normalization']['display'] = r'$\nu$'
expected['Display properties']['number-header'] = r'$P_\nu(f)$'
assert after == expected
assert list(before['Parameters']) == list(after['Parameters'])
assert list(before['Numbers']) == list(after['Numbers'])
assert before['Numbers'] == after['Numbers']
assert after['Parameters']['normalization']['display'] == r'$\nu$'
assert after['Display properties']['number-header'] == r'$P_\nu(f)$'

def interval(text):
    q = Fraction(text)
    center = QQ(q.numerator)/QQ(q.denominator)
    decimal = Decimal(text)
    radius = QQ(10)**ZZ(decimal.as_tuple().exponent)
    assert len(decimal.as_tuple().digits) == 100
    assert center > radius > 0
    return center-radius, center+radius

forms = after['Numbers']
assert len(forms) == 138
for form, entries in forms.items():
    assert list(entries) == ['integral', 'index-normalized']
    level = ZZ(form.split('.')[0])
    index = QQ(level)
    for prime in level.prime_divisors():
        index *= 1 + QQ(1)/prime
    assert index in ZZ and index>0
    lo, hi = interval(entries['integral'])
    norm_lo, norm_hi = interval(entries['index-normalized'])
    assert max(lo,index*norm_lo)<=min(hi,index*norm_hi),form

encoded = json.dumps(after['Numbers'],ensure_ascii=False,separators=(',',':')).encode()
print(json.dumps({
    'table':'T684', 'sage_version':sage_version,
    'skill_manifest':'agents/runs/20261102T203248Z-repair-skills/manifest.json',
    'skill_sha256':{'local':'a2b28d9953264d7b0ca62663785c2952190c5be6d6d3597fd695d9a54d606278','live':'a2b28d9953264d7b0ca62663785c2952190c5be6d6d3597fd695d9a54d606278'},
    'only_expected_two_fields_changed':True,
    'entries_and_order_unchanged':True,
    'entries':2*len(forms), 'positive_100_significant_digit_entries':2*len(forms),
    'exact_interval_normalization_checks':len(forms),
    'numbers_sha256':hashlib.sha256(encoded).hexdigest(),
    'new_values_computed':0,
    'limitations':'Checks preservation and exact interval compatibility under the stated positive-integer normalization. Does not recompute the integrals or certify analytic error bounds.'
},indent=2))
