"""Portable record-integrity check; does not rerun or replace numerical admission."""
import argparse
import gzip
import hashlib
import json
from pathlib import Path
import numpy as np


def main():
    parser=argparse.ArgumentParser()
    parser.add_argument('--packet',type=Path,required=True)
    args=parser.parse_args()
    raw=args.packet.read_bytes()
    identity=(len(raw),hashlib.sha256(raw).hexdigest())
    encoded=(2869078,'2a81501bed03e97dbf5ed6df9ef96b6e452669eed7bb628d98e530c35dc8c236')
    decoded=(7093727,'3434ea71bb5e24214b7a9697b425a408952f4541ca4598c61f935c7fdf9e61c3')
    if identity==encoded:
        raw=gzip.decompress(raw)
        if (len(raw),hashlib.sha256(raw).hexdigest())!=decoded:
            raise ValueError('Decoded record identity differs')
    elif identity!=decoded:
        raise ValueError('Record is neither declared gzip nor declared HTTP-decoded JSON')
    packet=json.loads(raw)
    if packet['formatVersion']!=1 or packet['source']['totalOnMeanPowerErgS']!=1e43:
        raise ValueError('Wrong record schema/source')
    if set(packet['arrays'])!=set(packet['arrayIdentities']):
        raise ValueError('Array key set mismatch')
    decoded={}
    for key,row in packet['arrayIdentities'].items():
        dtype=np.dtype(row['dtype'])
        if dtype not in [np.dtype('float64'),np.dtype('int64')]:
            raise ValueError('Unexpected record dtype')
        value=np.asarray(packet['arrays'][key],dtype=dtype)
        if list(value.shape)!=row['shape'] or value.nbytes!=row['bytes']:
            raise ValueError('Array shape/size differs: '+key)
        if hashlib.sha256(np.ascontiguousarray(value).tobytes()).hexdigest()!=row['sha256']:
            raise ValueError('Array binary64/int64 identity differs: '+key)
        decoded[key]=value
    if decoded['pulseRhoVelocityPressureCode'].shape!=(12,4096,3):
        raise ValueError('Full native radial/time extent missing')
    if decoded['coolingRhoVelocityPressureCode'].shape!=(12,4096,3):
        raise ValueError('Full matching control missing')
    if packet['defaultWaveSnapshotIndex']!=6 or decoded['waveTimesMyr'][6]!=30:
        raise ValueError('Default is not the actual30Myr field')
    source=packet['source']
    closure=abs((source['twoBubbleInputJ']+source['thermalReleaseJ'])/source['actualTotalInputJ']-1)
    if closure>1e-12 or abs(source['allocatedBubblePowerErgS']/source['totalOnMeanPowerErgS']-.95)>1e-12:
        raise ValueError('Actual95/5 energy budget mismatch')
    if not (packet['soundNumerics']['spatialMaximum']<=.05 and packet['soundNumerics']['temporalMaximum']<=.01):
        raise ValueError('Recorded numerical admission absent')
    if packet['AGNShockScope']!='FAIL_SCOPE_NOT_SHOCK' or not packet['RHReference']['cartesianCoordinatesAreNotKpc']:
        raise ValueError('Current AGN and independent RH scopes conflated')
    print(json.dumps({'status':'PASS_PACKET_ARRAY_IDENTITIES_AND_RECORDED_SCOPE','arrays':len(decoded),
        'actualBudgetClosure':closure,'spatialMaximum':packet['soundNumerics']['spatialMaximum'],
        'temporalMaximum':packet['soundNumerics']['temporalMaximum'],
        'AGNShockScope':packet['AGNShockScope'],'newPDEOrODECalls':0,
        'boundary':'Integrity and recorded admission only; not an independent rerun of numerical science or Perseus tutorial.'}))


if __name__=='__main__':
    main()
