#include "pressure_age.h"
#include <assert.h>
#include <stdio.h>
#include <limits.h>
static void zeroed(const pv_state *s){assert(!s->result.decoded&&!s->result.suction_valid&&!s->result.raw_signed&&!s->result.pressure_millipa);}
int main(void){
 pv_state s;xp_result good={123,456789,true,true},bad={123,456789,false,true};
 assert(!pv_init(NULL,1000,100));assert(!pv_init(&s,0,100));
 pv_begin(&s,0);pv_complete(&s,&good,0);assert(s.status==PV_CONFIG_ERROR);zeroed(&s);
 assert(!pv_init(&s,1000,0));assert(!pv_init(&s,0x80000000u,1));assert(!pv_init(&s,1,UINT32_MAX));
 assert(pv_init(&s,1000,100));assert(s.status==PV_EMPTY);zeroed(&s);
 pv_complete(&s,&good,0);assert(s.status==PV_BAD_RESULT);zeroed(&s);
 pv_begin(&s,10);pv_complete(&s,&good,109);assert(s.status==PV_RECENT_READ&&!s.result.suction_valid);
 assert(!pv_tick(&s,1108));assert(pv_tick(&s,1109));assert(s.status==PV_EXPIRED);zeroed(&s);
 assert(!pv_tick(&s,1110));pv_begin(&s,2000);pv_complete(&s,&good,2100);assert(s.status==PV_READ_TIMEOUT);zeroed(&s);
 pv_begin(&s,2200);assert(!pv_tick(&s,2299));assert(pv_tick(&s,2300));pv_complete(&s,&good,2300);assert(s.status==PV_BAD_RESULT);zeroed(&s);
 pv_begin(&s,3000);pv_complete(&s,&bad,3001);assert(s.status==PV_BAD_RESULT);zeroed(&s);
 pv_begin(&s,3100);pv_complete(&s,NULL,3101);zeroed(&s);
 pv_begin(&s,3200);pv_complete(&s,&good,3201);pv_begin(&s,3300);zeroed(&s);
 pv_complete(&s,&good,3301);pv_complete(&s,&good,3302);assert(s.status==PV_BAD_RESULT);zeroed(&s);
 /* 64-bit independent elapsed-time reference around every uint32 rollover. */
 unsigned cases=0;
 for(unsigned i=0;i<2000;i++){
  uint64_t start=(uint64_t)UINT32_MAX-999+i;
  assert(pv_init(&s,1000,100));pv_begin(&s,(uint32_t)start);
  uint64_t finish=start+(i%101);pv_complete(&s,&good,(uint32_t)finish);
  if(finish-start>=100){assert(s.status==PV_READ_TIMEOUT);zeroed(&s);cases++;continue;}
  for(unsigned age=0;age<=1005;age++){
   pv_tick(&s,(uint32_t)(finish+age));
   assert((s.status==PV_RECENT_READ)==(finish+age-finish<1000));
   if(age>=1000)zeroed(&s);else assert(s.result.pressure_millipa==456789&&!s.result.suction_valid);
   cases++;
  }
 }
 pv_begin(NULL,0);pv_complete(NULL,NULL,0);assert(!pv_tick(NULL,0));
 printf("PASS pressure host-read age: %u independent timeline cases; limits, wrap, invalidation, recovery and permission isolation\n",cases);
}
