"""Authored normalized REGISTER ledger, not SIP URI/parser/registrar implementation."""
import json
OWN='sip:ua-a@192.0.2.10';OTHER='sip:ua-b@192.0.2.20'
def snapshot(now,confirmed_at,contacts,pending=False):
    if type(now)is not int or type(confirmed_at)is not int or now<confirmed_at:raise ValueError('ordered authored integer seconds')
    own=[x for x in contacts if x['contact']==OWN]
    if len(own)>1:raise ValueError('normalized exact contacts must be unique')
    if pending:return {'now':now,'state':'unknown_after_unanswered_refresh','last_confirmed_deadline':confirmed_at+own[0]['granted_expires']if own else None,'currently_registered_proven':False}
    if not own or own[0]['granted_expires']==0:return {'now':now,'state':'confirmed_own_binding_absent','currently_registered_proven':False}
    deadline=confirmed_at+own[0]['granted_expires']
    return {'now':now,'state':'within_last_confirmed_lifetime'if now<deadline else'last_confirmed_lifetime_elapsed','last_confirmed_deadline':deadline,'currently_registered_proven':False}
def demo():
    requested=300;contacts=[{'contact':OWN,'granted_expires':120},{'contact':OTHER,'granted_expires':900}]
    original=json.loads(json.dumps(contacts));initial=snapshot(0,0,contacts);assert initial['last_confirmed_deadline']==120
    # A query has no Contact, and this model does not mutate bindings.
    query={'at':60,'request_contact':None,'response_contacts':[{'contact':OWN,'granted_expires':60},{'contact':OTHER,'granted_expires':840}]};assert contacts==original
    query_state=snapshot(60,60,query['response_contacts']);assert query_state['last_confirmed_deadline']==120
    refresh={'at':90,'requested_expires':300,'response_at':91,'contacts':[{'contact':OWN,'granted_expires':120},{'contact':OTHER,'granted_expires':809}]}
    renewed=snapshot(110,91,refresh['contacts']);assert renewed['last_confirmed_deadline']==211
    confirmed_old_elapsed=snapshot(121,0,contacts);assert confirmed_old_elapsed['state']=='last_confirmed_lifetime_elapsed'
    unknown=[snapshot(t,0,contacts,True)for t in [100,121]];assert all(x['state']=='unknown_after_unanswered_refresh'for x in unknown)
    removed=snapshot(101,101,[{'contact':OTHER,'granted_expires':799}]);assert removed['state']=='confirmed_own_binding_absent'
    assert contacts==original
    return {'authored_not_registrar_trace':True,'own_exact_contact':OWN,'other_contact_is_not_owned':OTHER,'initial_request_expires':requested,'confirmed_response_at_0':contacts,'initial':initial,'query_without_contact':query,'query_state_unchanged_deadline':query_state,'refresh_with_confirmed_response':refresh,'renewed':renewed,'no_confirmed_refresh_last_lifetime_elapsed':confirmed_old_elapsed,'refresh_response_unknown_before_and_after_old_deadline':unknown,'own_removal_request':{'at':100,'contact':OWN,'expires':0},'own_expires_zero_removal_response':removed,'scope':'No URI equivalence, clocks/skew, credentials, network state, registrar side effects or call/media success tested. confirmed lifetime is historical evidence; unanswered refresh leaves current server state unknown.'}
if __name__=='__main__':print(json.dumps(demo(),indent=2))
