"""Check every stored T691 value and the functional equation after read-back.
Run with SageMath, NUMBERDB_API_KEY configured, and generate.py plus
numerical-evidence.json beside this file. Never writes to NumberDB.
"""
import os,sys,json,hashlib
from pathlib import Path
from decimal import Decimal, localcontext
import numberdb.sage as numberdb
from sage.rings.real_mpfr import RealField
from sage.rings.complex_mpfr import ComplexField
from sage.rings.integer_ring import ZZ
from generate import RankinSelbergCritical


def records_of(d):
    # Reuse the client's nested/grouped-record reader. All five parameters
    # of this table are integers, so its comma-separated identities are clear.
    from numberdb._generate import _stored_entries
    names=list(d['Parameters'])
    out=[]
    for identity,value in _stored_entries(d).items():
        parts=identity.split(',')
        assert len(parts)==len(names)==5
        out.append({'params':dict(zip(names,parts)),'number':value})
    return out


def run():
    if os.environ.get('NUMBERDB_KEY_FROM_STDIN')=='1':
        key=sys.stdin.read().strip()
        if '=' in key and key.split('=',1)[0].isidentifier():key=key.split('=',1)[1].strip().strip('\"\'')
        os.environ['NUMBERDB_API_KEY']=key
    report=RankinSelbergCritical().verify(sample=None)
    print('VERIFY',report,flush=True);assert report.ok
    doc=numberdb.table('T691');rows=records_of(doc);assert len(rows)==66
    evidence=json.loads(Path(__file__).with_name('numerical-evidence.json').read_text())
    independent={(x['k'],x['i'],x['s']):x for x in evidence['independent_checks']['comparisons']}
    R=RealField(800);C=ComplexField(800); stored={}; radii={};max_fe=R(0)
    for row in rows:
        p=row['params'];k,i,ell,j,s=[int(p[n]) for n in ('k','i','ell','j','s')]
        assert (ell,j)==(12,1)
        with localcontext() as ctx:
            ctx.prec=300
            v=Decimal(row['number']);u=Decimal(10)**v.as_tuple().exponent
            lo=R(str(v-u));hi=R(str(v+u));mid=R(str(v));rad=R(str(u))
        x=C(independent[k,i,s]['value'])
        assert lo<=x.real()<=hi and abs(x.imag())<R(10)**-130
        stored[k,i,s]=mid;radii[k,i,s]=rad
    for (k,i,s),v in stored.items():
        t=k+11-s
        factor=(2*R.pi())**(2*(t-s))*ZZ(s-1).factorial()*ZZ(s-12).factorial()/(ZZ(t-1).factorial()*ZZ(t-12).factorial())
        err=abs(stored[k,i,t]-v*factor)
        allowed=radii[k,i,t]+abs(factor)*radii[k,i,s]
        assert err<=allowed,(k,i,s)
        max_fe=max(max_fe,err/abs(stored[k,i,t]))
    print('READBACK_JSON '+json.dumps({'table':'T691','entries':66,'generator_matched':report.matched,
       'independent_values_inside_written_intervals':66,'functional_equation_pairs_checked':66,
       'max_relative_functional_equation_residual':str(max_fe),'status':'passed'}),flush=True)

if __name__=='__main__':run()
