#include "vacuum_panel_runtime.h"
#include <assert.h>
#include <stdio.h>
static vpr_state s;static uint32_t now;static vpr_output o;
static void feed(uint16_t raw,bool p,bool valid,bool fault,bool ready,unsigned n){
 for(unsigned i=0;i<n;i++){now+=10;o=vpr_step(&s,raw,valid,p,fault,false,ready,now);}
}
static void reset(uint32_t start){vpr_init(&s);now=start;feed(4095,false,true,false,false,4);}
static void power_click(void){feed(4095,true,true,false,false,3);feed(4095,false,true,false,false,3);}
int main(void){
 reset(0);assert(o.keys_valid&&o.ui.level==1&&!o.ui.run_requested);
 power_click();assert(o.ui.run_requested);
 feed(2048,false,true,false,false,3);assert(o.ui.level==2&&o.ui.run_requested);
 feed(2048,false,true,false,false,20);assert(o.ui.level==2);
 feed(4095,false,true,false,false,3);feed(2815,false,true,false,false,3);
 assert(o.ui.level==1&&o.ui.run_requested);
 feed(4095,false,true,false,false,3);power_click();assert(!o.ui.run_requested);
 /* All four levels saturate, and each held key creates only one edge. */
 for(unsigned i=0;i<6;i++){feed(4095,false,true,false,false,3);feed(2048,false,true,false,false,3);}
 assert(o.ui.level==4);
 for(unsigned i=0;i<6;i++){feed(4095,false,true,false,false,3);feed(2815,false,true,false,false,3);}
 assert(o.ui.level==1);
 /* Power bounce under20ms creates no command. */
 reset(0);for(unsigned i=0;i<10;i++){feed(4095,true,true,false,false,1);feed(4095,false,true,false,false,1);}
 assert(!o.ui.run_requested);feed(4095,false,true,false,false,3);power_click();assert(o.ui.run_requested);
 /* Unknown ADC immediately cancels run. Held power after recovery is primed. */
 feed(500,true,true,false,false,1);assert(!o.keys_valid&&!o.ui.run_requested);
 feed(4095,true,true,false,false,4);assert(!o.ui.run_requested);
 feed(4095,false,true,false,false,3);power_click();assert(o.ui.run_requested);
 feed(4095,false,false,false,false,1);assert(!o.ui.run_requested);
 /* Fault dominates even during a valid ladder transition. */
 reset(0);power_click();feed(2048,true,true,true,false,1);assert(!o.ui.run_requested);
 feed(2048,true,true,false,false,4);assert(!o.ui.run_requested);
 feed(4095,false,true,false,false,3);power_click();assert(o.ui.run_requested);
 /* Service gap cancels and does not treat a held key as a fresh press. */
 now+=101;o=vpr_step(&s,4095,true,true,false,false,false,now);assert(!o.ui.run_requested);
 feed(4095,true,true,false,false,4);assert(!o.ui.run_requested);
 feed(4095,false,true,false,false,3);power_click();assert(o.ui.run_requested);
 /* Strictly >5s, single learning pulse, and no deferred ready activation. */
 reset(0);feed(1668,false,true,false,true,3);uint32_t start=now;
 while((uint32_t)(now-start)<5000u){feed(1668,false,true,false,true,1);assert(!o.ui.learning_request);}
 feed(1668,false,true,false,true,1);assert(o.ui.learning_request&&!o.ui.run_requested);
 feed(1668,false,true,false,true,1);assert(!o.ui.learning_request);
 reset(0);feed(1668,false,true,false,false,510);assert(!o.ui.learning_request);
 feed(1668,false,true,false,true,100);assert(!o.ui.learning_request);
 feed(4095,false,true,false,true,3);feed(1668,false,true,false,true,510);
 assert(!o.ui.learning_request); /* pulse already consumed before final sample */
 /* Boot-held power and both keys never become commands. */
 vpr_init(&s);now=0;feed(1668,true,true,false,true,600);
 assert(!o.ui.run_requested&&!o.ui.learning_request&&o.ui.level==1);
 /* Wrap-safe timing. */
 reset(0xffffffd0u);power_click();assert(o.ui.run_requested);
 /* Actual 12-bit classifier exercised across all input values after an active request. */
 unsigned bad=0;
 for(unsigned raw=0;raw<65536u;raw++){
  reset(0);power_click();feed((uint16_t)raw,false,true,false,false,1);
  if(pk_classify((uint16_t)raw)==PK_INVALID){assert(!o.ui.run_requested&&!o.keys_valid);bad++;}
 }
 assert(bad==64397u);
 puts("PASS panel runtime: levels/hold/bounce/ADC rejection/fault/gap/wrap/all65536 ADC values");
}
