/* Complete C11 host: rejection reason, flush watermarks and script exceptions. */
#include "sqs_map.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
static void ok(int code){if(code){fprintf(stderr,"%s\n",sqsm_map_last_error());assert(!code);}}
static void rejection(sqsm_map_t map,const char *request,int expected,const char *reason,uint64_t since){
 sqsm_map_bytes_t out={NULL,0,0};
 assert(sqsm_map_source_json(map,(const uint8_t*)request,strlen(request),&out)==expected);
 assert(!out.data&&!out.len&&!out.allocation);
 assert(sqsm_map_flush_json(map,since,0,&out)==expected);
 assert(!out.data&&!out.len&&!out.allocation);
 const char *error=sqsm_map_last_error();char key[96];snprintf(key,sizeof(key),"\"code\":\"%s\"",reason);
 assert(strstr(error,key)&&strstr(error,"\"commandSequence\"")&&strstr(error,"\"submittedSequence\""));
}
int main(void){
 sqsm_map_t map=0;sqsm_map_bytes_t out={NULL,0,0};ok(sqsm_map_create(128,96,&map));
 rejection(map,"{\"method\":\"removeSource\",\"args\":[\"missing\"]}",SQSM_MAP_NOT_FOUND,"NOT_FOUND",0);
 ok(sqsm_map_flush_json(map,1,0,&out));ok(sqsm_map_bytes_free(out.allocation));
 const char *add="{\"method\":\"addSource\",\"args\":[\"reason\",{\"type\":\"geojson\",\"data\":{\"type\":\"FeatureCollection\",\"features\":[]}}]}";
 ok(sqsm_map_source_json(map,(const uint8_t*)add,strlen(add),&out));ok(sqsm_map_bytes_free(out.allocation));
 rejection(map,add,SQSM_MAP_CONFLICT,"CONFLICT",1);
 ok(sqsm_map_flush_json(map,3,0,&out));ok(sqsm_map_bytes_free(out.allocation));
 rejection(map,"{\"method\":\"setData\",\"args\":[{\"id\":\"reason\",\"sourceInstanceId\":\"0\"},{\"type\":\"FeatureCollection\",\"features\":[]}]}",SQSM_MAP_STALE_HANDLE,"STALE_HANDLE",3);
 ok(sqsm_map_flush_json(map,4,0,&out));ok(sqsm_map_bytes_free(out.allocation));
 rejection(map,"{\"method\":\"addSource\",\"args\":[\"invalid\",{\"type\":\"geojson\",\"data\":{\"type\":\"FeatureCollection\",\"features\":\"invalid\"}}]}",SQSM_MAP_INVALID_ARGUMENT,"INVALID_ARGUMENT",4);
 ok(sqsm_map_flush_json(map,5,0,&out));ok(sqsm_map_bytes_free(out.allocation));
 if(sqsm_map_runtime_flags()&SQSM_MAP_SCRIPT){
  const char *codes[]={"CONFLICT","STALE_HANDLE","CANCELLED"};const int statuses[]={SQSM_MAP_CONFLICT,SQSM_MAP_STALE_HANDLE,SQSM_MAP_CANCELLED};
  for(int i=0;i<3;i++){char source[160];snprintf(source,sizeof(source),"throw Object.assign(new Error('known failure'),{code:'%s'});",codes[i]);
   assert(sqsm_map_script_run_json(map,(const uint8_t*)source,strlen(source),&out)==statuses[i]);assert(!out.data&&!out.len&&!out.allocation);assert(strstr(sqsm_map_last_error(),codes[i]));}
 }
 ok(sqsm_map_destroy(map));puts("map error C host: PASS (original reason, watermarks, recovery, cleared outputs, typed exceptions)");return 0;
}
