/* Self-contained native resource policy and response fixture. No HTTP client or JSON dependency.
 * Production hosts parse every returned request and download its URL with the
 * advertised maxBytes/deadline/origin policy before returning on this thread.
 */
#include "sqs_map.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void ok(int32_t result){if(result){fprintf(stderr,"%s\n",sqsm_map_last_error());assert(!result);}}
int main(void){
 sqsm_map_t map=0;sqsm_map_bytes_t out={NULL,0,0};uint32_t accepted=0;
 assert(sqsm_map_runtime_flags()&SQSM_MAP_HOST_RESOURCES);
 assert(sqsm_map_runtime_flags()&SQSM_MAP_RESOURCE_POLICY);
 ok(sqsm_map_create(256,192,&map));
 const char *configuration="{\"method\":\"configure\",\"args\":[{\"resourceTimeoutMs\":20000,\"resourcePolicy\":{\"retries\":1,\"fallbacks\":[{\"prefix\":\"https://fixture.invalid/\",\"replacements\":[\"https://fallback.invalid/\"],\"attemptTimeoutMs\":4000}]}}]}";
 ok(sqsm_map_resource_policy_json(map,(const uint8_t*)configuration,strlen(configuration),&out));
 ok(sqsm_map_bytes_free(out.allocation));
 const char *style="{\"style\":\"https://fixture.invalid/style.json\",\"options\":{\"diff\":false}}";
 ok(sqsm_map_set_style_json(map,(const uint8_t*)style,strlen(style)));
 ok(sqsm_map_resource_requests_json(map,1,&out));
 char *json=(char*)malloc((size_t)out.len+1);assert(json);memcpy(json,out.data,(size_t)out.len);json[out.len]='\0';
 ok(sqsm_map_bytes_free(out.allocation));
 /* These two fields are extracted only from our fixed single-request fixture.
  * Use a proper JSON parser for arbitrary production request arrays. */
 assert(strstr(json,"\"requestPlan\":"));
 assert(strstr(json,"https://fallback.invalid/style.json"));
 assert(strstr(json,"\"retries\":1"));
 /* A production host executes requestPlan with a JSON parser and HTTP client. */
 const char *id_field=strstr(json,"\"id\":");const char *generation_field=strstr(json,"\"generation\":\"");assert(id_field&&generation_field);
 unsigned long id=strtoul(id_field+5,NULL,10);char generation[32]={0};
 const char *begin=generation_field+14;const char *end=strchr(begin,'"');assert(end&&(size_t)(end-begin)<sizeof(generation));memcpy(generation,begin,(size_t)(end-begin));
 char response[128];int length=snprintf(response,sizeof(response),"{\"generation\":\"%s\",\"id\":%lu}",generation,id);assert(length>0&&(size_t)length<sizeof(response));free(json);
 const char *download="{\"version\":8,\"sources\":{},\"layers\":[{\"id\":\"background\",\"type\":\"background\",\"paint\":{\"background-color\":\"#114477\"}}]}";
 ok(sqsm_map_resource_response(map,(const uint8_t*)response,(uint64_t)length,(const uint8_t*)download,strlen(download),&accepted));assert(accepted==1);
 for(int frame=0;frame<4;frame++){
  ok(sqsm_map_render_rgba(map,&out));assert(out.len==256u*192u*4u);
  assert(abs((int)out.data[0]-17)<=1&&abs((int)out.data[1]-68)<=1&&abs((int)out.data[2]-119)<=1&&out.data[3]==255);ok(sqsm_map_bytes_free(out.allocation));
  ok(sqsm_map_poll_events_json(map,&out));ok(sqsm_map_bytes_free(out.allocation));
 }
 style="{\"style\":null}";ok(sqsm_map_set_style_json(map,(const uint8_t*)style,strlen(style)));
 ok(sqsm_map_destroy(map));puts("native resource policy C host: PASS");return 0;
}
