#include "pressure_age.h"
static void invalidate(pv_state *s,pv_status status){
 s->result=(xp_result){0};s->status=status;
}
bool pv_init(pv_state *s,uint32_t age,uint32_t read){
 if(!s)return false;
 *s=(pv_state){0};s->max_age_ms=age;s->max_read_ms=read;
 if(!age||!read||age>=0x80000000u||read>=0x80000000u){
  invalidate(s,PV_CONFIG_ERROR);return false;
 }
 return true;
}
void pv_begin(pv_state *s,uint32_t now){
 if(!s||s->status==PV_CONFIG_ERROR)return;
 invalidate(s,PV_ACQUIRING);s->started_ms=now;
}
void pv_complete(pv_state *s,const xp_result *r,uint32_t now){
 if(!s||s->status==PV_CONFIG_ERROR)return;
 if(s->status!=PV_ACQUIRING){invalidate(s,PV_BAD_RESULT);return;}
 s->finished_ms=now;
 /* Exactly at the configured limit is expired, consistently with tick. */
 if((uint32_t)(now-s->started_ms)>=s->max_read_ms){
  invalidate(s,PV_READ_TIMEOUT);return;
 }
 if(!r||!r->decoded){invalidate(s,PV_BAD_RESULT);return;}
 s->result=*r;
 /* Reading bytes and decoding cannot qualify physical suction. */
 s->result.suction_valid=false;s->status=PV_RECENT_READ;
}
bool pv_tick(pv_state *s,uint32_t now){
 if(!s)return false;
 if(s->status==PV_RECENT_READ&&(uint32_t)(now-s->finished_ms)>=s->max_age_ms){
  invalidate(s,PV_EXPIRED);return true;
 }
 if(s->status==PV_ACQUIRING&&(uint32_t)(now-s->started_ms)>=s->max_read_ms){
  invalidate(s,PV_READ_TIMEOUT);return true;
 }
 return false;
}
