#include "host_stream_fixture.h"
int main(void){unsigned cases=0;
 for(unsigned wrap=0;wrap<2;++wrap){uint32_t n=wrap?UINT32_MAX-100:0;streaming(n);drill_debug_stream_received=drill_debug_stream_epoch=0;
  uint32_t now=n+60;
  for(unsigned seq=1;seq<=64;++seq){now+=25;timer2.CNT=now;assert(!drill_foreground_service(now)&&drill_dual_state==DU_STREAM&&drill_debug_stream_received==seq-1);++cases;
   now+=25;timer2.CNT=now;uint32_t ia=seq*31u,ib=4095u-seq*17u;transfer((ib<<16)|ia);assert(!drill_foreground_service(now));
   assert(drill_debug_stream_received==seq&&drill_debug_stream_epoch==seq*2&&drill_debug_stream_sample.sequence==seq&&drill_debug_stream_sample.ia_raw==ia&&drill_debug_stream_sample.ib_raw==ib&&!drill_debug_stream_sample.calibration_verified&&drill_debug_stream_sample.observed_us==now);
   assert(drill_dual_state==DU_STREAM&&!ds_pending&&!dma.IFCR&&!(dma.ISR&(DMA_ISR_HTIF1|DMA_ISR_TCIF1)));++cases;
  }
  drill_dual_stream_stop();stream_off();
 }
 /* Full foreground retains hard-off response when each independent owner changes. */
 for(unsigned mode=0;mode<20;++mode){streaming(0);drill_debug_stream_received=drill_debug_stream_epoch=0;timer2.CNT=80;transfer(0x04560123);
  if(mode==0)timer.CCR4^=1;if(mode==1)spi.CR2^=1;if(mode==2)adc1.SQR1^=1;if(mode==3)dma_channel.CCR^=1;if(mode==4)mux.CCR^=1;
  if(mode==5)ga.IDR&=~(1u<<6);if(mode==6)rcc.CR&=~RCC_CR_PLLRDY;if(mode==7)timer2.PSC^=1;if(mode==8)adc2.ISR|=ADC_ISR_OVR;if(mode==9)timer.CCER=1;
  if(mode==10)drill_config.state=DC_SUBMIT;if(mode==11)timer2.CNT=111;if(mode==12)timer.CR1&=~TIM_CR1_CEN;if(mode==13)ga.ODR|=1u<<5;
  if(mode==14)gb.IDR|=1u;if(mode==15)gf.IDR=0;if(mode==16)ga.ODR&=~(1u<<12);if(mode==17)adc_common.CCR^=1;if(mode==18)sampling_owned=false;if(mode==19)ds_pending=true;
  assert(drill_foreground_service(80));stream_off();assert(drill_debug_stream_received==0&&drill_debug_stream_epoch==0);++cases;
 }
 /* A sleeping driver/non-stream mode is still serviced and may idle. */
 fixture();drill_dual_state=DU_IDLE;drill_config.state=DC_IDLE;timer2.CNT=80;assert(drill_foreground_service(80));++cases;
 fixture();drill_dual_state=DU_IDLE;drill_config=(dc_runtime){0};assert(drill_config_bench_begin(0,true)&&drill_config.state==DC_SLEEP&&!(gf.ODR&2u));
 timer2.CNT=999;assert(drill_foreground_service(999)&&drill_config.state==DC_SLEEP);timer2.CNT=1000;assert(drill_foreground_service(1000)&&drill_config.state==DC_WAKE&&(gf.ODR&2u));++cases;
 /* The completion may be observed later than take's entry timestamp. */
 streaming(0);drill_debug_stream_received=drill_debug_stream_epoch=0;timer2.CNT=80;transfer(0x04560123);stream_race=5;
 assert(!drill_foreground_service(80)&&drill_dual_state==DU_STREAM&&drill_debug_stream_received==1&&drill_debug_stream_sample.observed_us==82);++cases;
 /* A delay after publication into the pending slot must not reach SWD. */
 streaming(0);drill_debug_stream_received=drill_debug_stream_epoch=0;timer2.CNT=80;transfer(0x04560123);stream_race=6;
 assert(drill_foreground_service(80));stream_off();assert(!drill_debug_stream_received&&!drill_debug_stream_epoch);++cases;
 printf("%u REAL FOREGROUND / EPOCH / HARD-OFF SCENARIOS PASS\n",cases);
}
