"""Illustrative usage ledger with explicit correction attribution. No billing API."""
from collections import defaultdict
from copy import deepcopy
from pathlib import Path
import json
ROOT=Path(__file__).resolve().parent
BASE=dict(tenant='customer-a',meter='completed_pages')
events=[dict(BASE,id='u1',kind='usage',period='2026-05',units=100),dict(BASE,id='u1',kind='usage',period='2026-05',units=100),dict(BASE,id='u2',kind='usage',period='2026-06',units=40),dict(BASE,id='c1',kind='correction',ref='u1',units=-20),dict(BASE,id='u3',kind='usage',period='2026-05',units=30),dict(BASE,id='c1',kind='correction',ref='u1',units=-20)]
def apply(events):
 seen={};totals=defaultdict(int);remaining={};trace=[]
 for e in events:
  key=(e['tenant'],e['meter'],e['id'])
  if key in seen:
   if seen[key]!=e:raise ValueError('conflicting event identity')
   trace.append(dict(id=e['id'],outcome='duplicate'));continue
  if type(e['units'])is not int:raise ValueError('integer units required')
  if e['kind']=='usage':
   if e['units']<0:raise ValueError('usage must be nonnegative')
   period=e['period'];remaining[key]=e['units']
  elif e['kind']=='correction':
   original=(e['tenant'],e['meter'],e['ref'])
   if original not in remaining:raise ValueError('unknown usage reference in tenant and meter')
   if e['units']>=0 or remaining[original]+e['units']<0:raise ValueError('invalid correction amount')
   period=seen[original]['period'];remaining[original]+=e['units']
  else:raise ValueError('unknown event kind')
  seen[key]=deepcopy(e);totals[period]+=e['units'];trace.append(dict(id=e['id'],outcome='applied',period=period,delta=e['units']))
 return dict(totals),trace
sums,trace=apply(events)
assert sums=={'2026-05':110,'2026-06':40}
assert sum(r['outcome']=='duplicate'for r in trace)==2
negative=[dict(BASE,id='x1',kind='correction',ref='missing',units=-1),dict(BASE,id='x2',kind='correction',ref='u1',units=-101),dict(BASE,id='u1',kind='usage',period='2026-05',units=101)]
rejected=[]
for e in negative:
 try:apply([events[0],e])
 except ValueError as error:rejected.append(str(error))
 else:raise AssertionError('invalid event accepted')
(ROOT/'events.json').write_text(json.dumps(events,indent=2)+'\n')
(ROOT/'ledger.json').write_text(json.dumps(trace,indent=2)+'\n')
(ROOT/'results.json').write_text(json.dumps(dict(deliveries=6,applied=4,duplicates=2,periodTotals=sums,rawDeliverySum=sum(e['units']for e in events),negativeCasesRejected=rejected,scope='Assigned open accounting periods, one tenant and meter, integer units. No invoices, pricing, tax or provider API.'),indent=2)+'\n')
print(json.dumps(sums))
