#include "drill_button.h"
#include <assert.h>
#include <stdio.h>
static uint32_t now;
static unsigned events;static dc_command last;
static void sample(db_state*s,bool pressed,unsigned ms){
 for(unsigned j=0;j<ms;j++){now+=1000;dc_command c=db_sample(s,now,pressed);if(c!=DC_NONE){events++;last=c;}}
}
static void click(db_state*s){
 sample(s,true,1);sample(s,false,1);sample(s,true,1);sample(s,false,1);sample(s,true,25);
 sample(s,false,1);sample(s,true,1);sample(s,false,25);
}
int main(void){
 for(int wrap=0;wrap<2;wrap++)for(int n=1;n<=5;n++){
  db_state s;now=wrap?UINT32_MAX-50000u:0;events=0;last=DC_NONE;
  db_init(&s,now,false);sample(&s,false,25);
  for(int i=0;i<n;i++){click(&s);sample(&s,false,50);}
  assert(events==0);sample(&s,false,500);assert(events==1);
  assert(last==(n==1?DC_TOGGLE_RUN_REQUEST:n==2?DC_REVERSE_REQUEST:n==3?DC_MODE_REQUEST:DC_REJECTED));
 }
 db_state s;now=0;events=0;db_init(&s,now,true);
 sample(&s,true,100);sample(&s,false,500);assert(events==0); /* held at boot */
 click(&s);sample(&s,false,500);assert(events==1);
 now=0;events=0;db_init(&s,now,false);sample(&s,false,25);click(&s);
 now+=30000;assert(db_sample(&s,now,false)==DC_NONE);sample(&s,false,600);assert(events==0);
 /* Fresh click required after a service gap; rapid bounce not an event. */
 for(int j=0;j<100;j++){sample(&s,true,1);sample(&s,false,1);}
 sample(&s,false,500);assert(events==0);click(&s);sample(&s,false,500);assert(events==1);
 puts("PASS: bounce rejection, 1/2/3/many clicks, TIM2 microsecond wrap, boot-held suppression, service-gap cancellation, fresh rearm");
}
