/* A complete ABI v1 scene clock client. Link with sqs_map; no JS runtime required. */
#include "sqs_map.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static uint64_t map;
static void check(int32_t status) {
    if(status){fprintf(stderr,"%s\n",sqsm_map_last_error());if(map)sqsm_map_destroy(map);exit(1);}
}
static char *call(const char *request) {
    sqsm_map_bytes_t out={0};check(sqsm_map_scene_json(map,(const uint8_t*)request,strlen(request),&out));
    char *text=malloc((size_t)out.len+1);if(!text)exit(2);
    memcpy(text,out.data,(size_t)out.len);text[out.len]=0;check(sqsm_map_bytes_free(out.allocation));return text;
}
static double elapsed(const char *owner) {
    char request[500];snprintf(request,sizeof(request),"{\"method\":\"getClock\",\"args\":[%s]}",owner);
    char *text=call(request),*field=strstr(text,"\"elapsedMs\":");if(!field)exit(3);
    double ms=strtod(field+12,NULL);puts(text);free(text);return ms;
}
int main(void) {
    check(sqsm_map_create(128,96,&map));
    char *created=call("{\"method\":\"create\",\"args\":[{\"id\":\"clock\"}]}");
    char *begin=strstr(created,"\"sceneInstanceId\":\"");if(!begin)exit(3);begin+=strlen("\"sceneInstanceId\":\"");
    char *end=strchr(begin,'"');if(!end||end-begin>128)exit(3);
    char identity[129];memcpy(identity,begin,(size_t)(end-begin));identity[end-begin]=0;free(created);
    char owner[300],request[500];snprintf(owner,sizeof(owner),"{\"id\":\"clock\",\"sceneInstanceId\":\"%s\"}",identity);
    if(elapsed(owner)!=0.)exit(3);
    const char *methods[]={"start","pause","resume","stop"};
    for(size_t i=0;i<4;i++) {
        snprintf(request,sizeof(request),"{\"method\":\"%s\",\"args\":[%s]}",methods[i],owner);
        free(call(request));double first=elapsed(owner),second=elapsed(owner);
        if(first<0.||second<first||((i==1||i==3)&&second!=first))exit(3);
    }
    snprintf(request,sizeof(request),"{\"method\":\"remove\",\"args\":[%s]}",owner);free(call(request));
    sqsm_map_bytes_t events={0};check(sqsm_map_poll_events_json(map,&events));check(sqsm_map_bytes_free(events.allocation));
    check(sqsm_map_destroy(map));map=0;puts("C shared monotonic scene clock: passed");return 0;
}
