#!/usr/bin/env python3
"""Offline integrity checks only. Does not fetch, decode, play, inspect or generate media."""
import argparse,csv,datetime,hashlib,json,pathlib,struct,xml.etree.ElementTree as ET
EXPECTED_TIMES=[0,2.11456,4.07808,6.0416,9.96864,12.08274,14.033572,15.104]
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
def main():
 p=argparse.ArgumentParser();p.add_argument('--out',type=pathlib.Path);args=p.parse_args();base=pathlib.Path(__file__).resolve().parent
 if args.out and args.out.exists():raise SystemExit('Refusing to overwrite an existing check receipt.')
 obs=json.loads((base/'observation.json').read_text());rows=list(csv.DictReader((base/'observation.csv').open(encoding='utf-8-sig')));samples=obs['samples'];checks={}
 def check(name,condition):
  if not condition:raise AssertionError(name)
  checks[name]=True
 check('eightOrderedDistinctSampleTimes',[s['videoCurrentTimeSeconds'] for s in samples]==EXPECTED_TIMES and len(set(EXPECTED_TIMES))==8)
 check('allSamplesWithinObservedDuration',all(0<=t<=obs['browserMediaState']['durationSeconds'] for t in EXPECTED_TIMES))
 check('observedBrowserState',obs['browserMediaState']=={'durationSeconds':15.104,'readyState':4,'videoWidth':1280,'videoHeight':720})
 check('unlistenedAudioNotClaimedInspected',obs['audio']['status']=='not-listened' and obs['audio']['claimsAboutMusicSoundEffectsVoiceOrBeat'] is False and all(s['audioStatus']=='not-listened' for s in samples))
 check('notPreciseCutsOrFrameIndices',all(s['exactShotBoundary'] is False and s['frameIndex'] is None for s in samples))
 check('noRedistributedScreenshotsOrSourceMediaOrPrompt',not obs['screenshotsPubliclyIncluded'] and not obs['remoteSourceMediaPubliclyRedistributed'] and not obs['sourcePromptPubliclyRedistributed'])
 check('noModelReproductionOrCompletedAudioBlueprint',not obs['newModelTaskRun'] and not obs['independentlyReproduced'] and not obs['audioEnhancedBlueprintComplete'])
 check('eightPrivateScreenshotDigestRecords',len({s['internalScreenshotBinding']['sha256'] for s in samples})==8 and all(len(s['internalScreenshotBinding']['sha256'])==64 and s['internalScreenshotBinding']['publiclyRedistributed'] is False for s in samples))
 check('noFabricatedWallClockTime',obs['browserObservedAtUtc'] is None and bool(obs['recordAssembledAtUtc']))
 check('csvHasEightMatchingRows',len(rows)==8)
 for row,s in zip(rows,samples):
  check('csvIdentityAndTime-'+s['sampleId'],row['sample_id']==s['sampleId'] and float(row['video_current_time_seconds'])==s['videoCurrentTimeSeconds'])
  for lang in ['en','zh']:
   for f in ['observed','interpretation','boundary']:check('csv-'+s['sampleId']+'-'+lang+'-'+f,row[f+'_'+lang]==s['locales'][lang][f] and bool(row[f+'_'+lang]))
 for lang in ['en','zh']:ET.parse(base/('information-expansion.'+lang+'.svg'))
 check('twoWellFormedOriginalSvgDiagrams',True)
 cover=base/'cover-v1.png';header=cover.read_bytes()[:24];check('originalCoverPngIdentity',header[:8]==b'\x89PNG\r\n\x1a\n' and sha(cover)==obs['coverProvenance']['sha256']);w,h=struct.unpack('>II',header[16:24]);check('coverHasValidDimensions',w>0 and h>0)
 files=['observation.json','observation.csv','information-expansion.en.svg','information-expansion.zh.svg','cover-v1.png','README.en.md','README.zh.md','validate-observation.py']
 result={'schemaVersion':1,'blueprintId':'blueprint-32','checkType':'offline-observation-metadata-consistency','checkedAtUtc':datetime.datetime.now(datetime.timezone.utc).isoformat(timespec='seconds'),'checks':checks,'passedChecks':len(checks),'files':{f:{'sha256':sha(base/f),'bytes':(base/f).stat().st_size} for f in files},'networkCalls':0,'sourceScreenshotsDecodedByThisCheck':False,'sourceMediaDecoded':False,'audioListened':False,'newModelTaskRun':False,'originalAudioEnhancedBlueprintComplete':False,'scope':'Checks the supplied observation record and original asset identities; does not independently re-inspect private screenshots or validate video contents.'}
 if args.out:args.out.write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n')
 print(json.dumps({'passedChecks':len(checks),'coverDimensions':[w,h],'networkCalls':0,'mediaDecoded':False}))
if __name__=='__main__':main()
