#include "lamp_driver_diagnostics.h"
#include "lamp_i2c_read.h"
#include "lamp_i2c_owner.h"
static bool paused;
static lamp_i2c_read reader;
static pca_async_bank bank;
static bool begin(void *ctx,uint8_t a,uint8_t reg,uint32_t now){return lamp_i2c_read_start(ctx,a,reg,now);}
static void poll(void *ctx,uint32_t now){lamp_i2c_read_poll(ctx,now);}
static bool take(void *ctx,uint32_t now,uint8_t *v){return lamp_i2c_read_get(ctx,now,v);}
static bool failed(void *ctx){return ((lamp_i2c_read *)ctx)->state==LIR_FAILED;}
static void cancel(void *ctx){lamp_i2c_read_cancel(ctx);}
bool lamp_driver_diagnostics_init(const uint32_t eligible[3],uint32_t now){
 /* Called only by exclusive diagnostic runtime owner after reset recovery.
  * Never reinitialize over an active transport/bank. */
 if(reader.bound)return false;
 lamp_i2c_read_reset(&reader);
 return pca_async_init(&bank,&reader,(pca_async_ops){begin,poll,take,failed,cancel},eligible,now);
}
void lamp_driver_diagnostics_poll(uint32_t now){if(!paused)pca_async_poll(&bank,now);}
bool lamp_driver_diagnostics_get(uint32_t now,pca_async_snapshot *out){return !paused && pca_async_get(&bank,now,out);}

bool lamp_driver_diagnostics_failed(void){return bank.failed;}
void lamp_driver_diagnostics_abort(void){
 lamp_i2c_read_cancel(&reader);bank.valid=false;bank.failed=true;
}

bool lamp_driver_diagnostics_pause(uint32_t now){
 pca_async_snapshot snapshot;
 if(paused || bank.pending || !lamp_i2c_owner_idle() ||
    reader.state!=LIR_DONE || !pca_async_get(&bank,now,&snapshot))return false;
 paused=true;bank.valid=false;lamp_i2c_read_cancel(&reader);return true;
}
bool lamp_driver_diagnostics_resume(uint32_t now){
 if(!paused || !bank.bound || bank.failed || bank.pending ||
    reader.state!=LIR_DONE || !lamp_i2c_owner_idle())return false;
 bank.valid=false;bank.reads=0;bank.last_poll=bank.first_read=now;
 paused=false;return true;
}
