#!/usr/bin/env python3
"""Reproduce two descriptive views of fixed inputs. Standard library; no network or source edits."""
import argparse,hashlib,json
from collections import Counter
from pathlib import Path
PINS={'creators':'668b4bfbe392047a59621c573dda9bb75f1b5025a003fd5c94986840fad49e88','earnings':'d4d7771bf47ac2166a6ae6998e9b0c4a636080e026fb2da0409acc5973a3dd73'}
GEOGRAPHY=[('minneapolis','Minneapolis'),('st_paul','St. Paul'),('twin_cities_metro','Other Twin Cities metro'),('other_minnesota','Other documented Minnesota locations'),('minnesota_statewide','Minnesota; locality not established')]
def read_pinned(file,key):
 raw=Path(file).read_bytes()
 if hashlib.sha256(raw).hexdigest()!=PINS[key]:raise ValueError('Source edition mismatch: '+key)
 return json.loads(raw)
def derive(creators,earnings):
 rows=creators['records'];e=earnings['records'];assert len(rows)==47 and len(e)==32
 assert len({r['entity_id']for r in rows})==47 and len({r['record_id']for r in e})==32
 assert {r['geographic_scope']for r in rows}=={k for k,_ in GEOGRAPHY};assert {r['entity_type']for r in rows}=={'Person','Organization'}
 geography=[]
 for key,label in GEOGRAPHY:
  selected=[r for r in rows if r['geographic_scope']==key];n=Counter(r['entity_type']for r in selected)
  geography.append({'key':key,'label':label,'people':n['Person'],'organizations':n['Organization'],'total':len(selected),'organization_ids':[r['entity_id']for r in selected if r['entity_type']=='Organization']})
 assert sum(r['total']for r in geography)==47
 groups={}
 for r in e:
  url=r['source_url'];assert isinstance(url,str)and url.startswith('https://')
  g=groups.setdefault(url,{'url':url,'source_names':[],'publishers':[],'record_ids':[]})
  for field,k in [('source_name','source_names'),('publisher','publishers')]:
   if r[field]not in g[k]:g[k].append(r[field])
  g['record_ids'].append(r['record_id'])
 sourcegroups=[dict(g,count=len(g['record_ids']))for g in groups.values()]
 assert sum(g['count']for g in sourcegroups)==32
 return {'version':'1.0.0','source_sha256':PINS,'geography_by_entity_type':{'directory_entities':47,'people':sum(r['people']for r in geography),'organizations':sum(r['organizations']for r in geography),'rows':geography,'limitation':'Fixed professional-base evidence labels, not private residence, hometowns, fresh verification or a statewide census.'},'earnings_source_urls':{'observations':32,'literal_urls':len(sourcegroups),'source_name_labels':len({r['source_name']for r in e}),'publisher_labels':len({r['publisher']for r in e}),'groups':sourcegroups,'limitation':'Exact retained URL strings only; URLs, report names and publishers are not independent studies or samples. No financial values pooled.'}}
if __name__=='__main__':
 p=argparse.ArgumentParser(description=__doc__);p.add_argument('--creators',required=True);p.add_argument('--earnings',required=True);p.add_argument('--output');args=p.parse_args();result=derive(read_pinned(args.creators,'creators'),read_pinned(args.earnings,'earnings'));text=json.dumps(result,indent=2,ensure_ascii=False)+'\n'
 if args.output:Path(args.output).write_text(text)
 else:print(text,end='')
