#include "drill_encoder.h"
#include <assert.h>
#include <limits.h>
#include <stdio.h>
int main(void){
 de_state s;uint32_t t=0;
 assert(!de_init(0,0,0));assert(!de_init(&s,0,4));assert(de_sample(&s,1,0)==0);
 const uint8_t f[]={1,3,2,0},r[]={2,3,1,0};
 for(int wrap=0;wrap<2;wrap++){
  t=wrap?UINT32_MAX-1500u:0;assert(de_init(&s,t,0));
  for(int n=0;n<100;n++)for(int j=0;j<4;j++)assert(de_sample(&s,t+=1000,f[j])==1);
  assert(s.edge_position==400);
  for(int n=0;n<100;n++)for(int j=0;j<4;j++)assert(de_sample(&s,t+=1000,r[j])==-1);
  assert(s.edge_position==0 && s.invalid_transitions==0 && s.service_gaps==0);
 }
 assert(de_init(&s,0,0));assert(de_sample(&s,1000,1)==1);assert(de_sample(&s,1100,0)==-1);
 assert(de_sample(&s,1200,1)==1);assert(de_sample(&s,1300,0)==-1);assert(s.edge_position==0);
 assert(de_sample(&s,1400,3)==0 && s.invalid_transitions==1); /* skipped state */
 assert(de_sample(&s,1500,2)==1 && s.edge_position==1); /* resync */
 assert(de_sample(&s,3501,0)==0 && s.service_gaps==1 && s.edge_position==1);
 assert(de_sample(&s,4501,1)==1);assert(s.edge_position==2);
 assert(de_init(&s,0,0));s.edge_position=INT32_MAX;
 assert(de_sample(&s,1000,1)==0 && s.saturated && s.edge_position==INT32_MAX);
 assert(de_init(&s,0,0));s.edge_position=INT32_MIN;
 assert(de_sample(&s,1000,2)==0 && s.saturated && s.edge_position==INT32_MIN);
 assert(de_sample(&s,1001,4)==0 && !s.initialized);
 /* A complete unseen cycle leaves the SAME input state; cannot be detected. */
 assert(de_init(&s,0,0));assert(de_sample(&s,1000,0)==0 && s.invalid_transitions==0);
 puts("PASS: forward/reverse waveforms, edge bounce cancellation, skipped-state resync, >2ms gap, microsecond wrap, saturation, invalid input; unseen-cycle detection NOT claimed");
}
