#include "vacuum_ui.h"
#include <assert.h>
#include <stdio.h>
static uint32_t previous_ms;
static vui_input previous_input;
static vui_output step(vui_state*s,const vui_input*i,uint32_t t){
 while((uint32_t)(t-previous_ms)>100u){previous_ms+=100u;vui_step(s,&previous_input,previous_ms);}
 previous_ms=t;previous_input=*i;return vui_step(s,i,t);
}
int main(void){
 vui_state s;vui_input i={0};vui_output o;vui_init(&s);assert(s.level==1);vui_step(&s,&i,0);
 for(int j=0;j<10;j++){i.plus_pressed=true;step(&s,&i,j*2);i.plus_pressed=false;step(&s,&i,j*2+1);}assert(s.level==4);
 for(int j=0;j<10;j++){i.minus_pressed=true;step(&s,&i,100+j*2);i.minus_pressed=false;step(&s,&i,101+j*2);}assert(s.level==1);
 i.power_pressed=true;o=step(&s,&i,200);assert(o.run_requested);o=step(&s,&i,201);assert(o.run_requested);i.power_pressed=false;step(&s,&i,202);
 i.plus_pressed=i.minus_pressed=true;i.learning_resources_ready=true;
 o=step(&s,&i,1000);assert(o.level==1&&!o.learning_request);
 assert(!step(&s,&i,6000).learning_request);o=step(&s,&i,6001);assert(o.learning_request&&!o.run_requested);
 assert(!step(&s,&i,12000).learning_request);i.plus_pressed=i.minus_pressed=false;step(&s,&i,12001);
 i.plus_pressed=i.minus_pressed=true;i.learning_resources_ready=false;step(&s,&i,13000);assert(!step(&s,&i,18001).learning_request);
 i.learning_resources_ready=true;assert(!step(&s,&i,18002).learning_request); /* no deferred learning */
 i.plus_pressed=i.minus_pressed=false;step(&s,&i,18003);
 i.power_pressed=true;assert(step(&s,&i,18004).run_requested);
 i.fault=true;assert(!step(&s,&i,18005).run_requested);i.fault=false;assert(!step(&s,&i,18006).run_requested);
 i.power_pressed=false;step(&s,&i,18007);i.power_pressed=true;assert(step(&s,&i,18008).run_requested);
 i.learning_busy=true;assert(!step(&s,&i,18009).run_requested);i.learning_busy=false;assert(!step(&s,&i,18010).run_requested);
 vui_init(&s);i=(vui_input){0};previous_ms=UINT32_MAX-1100u;
 previous_input=i;vui_step(&s,&i,previous_ms);
 i.learning_resources_ready=true;i.plus_pressed=i.minus_pressed=true;
 step(&s,&i,UINT32_MAX-1000u);assert(!step(&s,&i,3999).learning_request);assert(step(&s,&i,4000).learning_request);
 /* Held at boot and a discontinuous long hold cannot trigger actions. */
 vui_init(&s);i=(vui_input){.power_pressed=true,.plus_pressed=true,.minus_pressed=true,.learning_resources_ready=true};
 assert(!vui_step(&s,&i,0).run_requested);assert(!vui_step(&s,&i,6001).learning_request);
 uint16_t duty=99,table[]={200,400,600,800};assert(!vui_lookup_duty(1,table,false,&duty)&&duty==0);
 assert(vui_lookup_duty(4,table,true,&duty)&&duty==800);table[2]=400;assert(!vui_lookup_duty(2,table,true,&duty)&&duty==0);
 assert(!vui_lookup_duty(5,table,true,&duty));
 puts("PASS: four-level bounds, power edge, >5s single learning request, unavailable-resource rejection without retry, fault/busy no autorestart, hold wrap, explicit qualified-duty table");
}
