// File: /workspace/github_c_makefile_star2_O0/antirez[P]stonky/stonky.c
// Function: getYahooData
ydata *getYahooData(int type, const char *symbol, const char *range, const char *interval, int ttl) {
    const char *apihost = "https://query2.finance.yahoo.com";
    sds url;

    /* Build the query according to the requested data. */
    if (type == YDATA_TS) {
        url = sdsnew(apihost);
        url = sdscat(url,"/v8/finance/chart/");
        url = sdscat(url,symbol);
        url = sdscatprintf(url,"?range=%s&interval=%s&includePrePost=false",
                           range,interval);
    } else if (type == YDATA_QUOTE || type == YDATA_INFO) {
        /* For pricing data we have to abuse the chart API, since Yahoo
         * in late 2023 stopped providing a real time API and the
         * quoteSummary API no logner works. Not everything is available
         * here, but we try to do our best. */
        url = sdsnew(apihost);
        url = sdscat(url,"/v8/finance/chart/");
        url = sdscat(url,symbol);
        url = sdscatprintf(url,"?interval=1d");
    } else {
        return NULL;
    }

    /* Get data via a blocking HTTP request. We try to perform more than
     * a single query since sometimes the Yahoo API will return a 500
     * error without any reason, but will work again immediately after. */
    int attempt = 0, maxattempts = 5;
    int res = C_ERR;

    /* Try using the cache if possible. */
    sds body = (ttl && CacheYahoo) ? kvGet(url) : NULL;
    int cached = body != NULL;

    if (body == NULL) {
        /* No caching or no cached version found? Fetch it from the
         * Yahoo servers. */
        while(attempt < maxattempts && res == C_ERR) {
            if (attempt > 0) usleep(100000);
            sdsfree(body);
            body = makeHttpCall(url,&res);
            attempt++;
        }
    } else {
        if (DebugMode) printf("Using cached version of %s\n", url);
        res = C_OK;
    }

    /* If we are using caching, and we just fetched a fresh version,
     * set it on the cache. */
    if (ttl && CacheYahoo && !cached) {
        kvSet(url,body,ttl);
    }

    sdsfree(url);
    if (res != C_OK) {
        sdsfree(body);
        return NULL;
    }

    /* Setup the empty object. */
    ydata *yd = malloc(sizeof(*yd));
    memset(yd,0,sizeof(*yd));
    yd->type = type;

    /* Extract the JSON fields and fills the data object. */
    cJSON *json = cJSON_Parse(body);
    sdsfree(body);

    if (type == YDATA_QUOTE || type == YDATA_INFO) {
        cJSON *meta = cJSON_Select(json,".chart.result[0].meta");
        cJSON *aux;
        if (meta == NULL) goto fmterr;
        if ((aux = cJSON_Select(meta,".symbol:s")) != NULL)
            yd->symbol = sdsnew(aux->valuestring);

        if ((aux = cJSON_Select(meta,".regularMarketPrice:n")) != NULL)
            yd->reg = aux->valuedouble;
        if ((aux = cJSON_Select(meta,".chartPreviousClose:n")) != NULL)
        {
            /* Compute the price change in percentage. */
            double prev_close = aux->valuedouble;
            double change = (yd->reg - prev_close) / prev_close * 100;
            yd->regchange = sdscatprintf(sdsempty(),"%02.g%%",change);
        }

        if ((aux = cJSON_Select(meta,".symbol:s")) != NULL)
            yd->name = sdsnew(aux->valuestring);
        if ((aux = cJSON_Select(meta,".exchangeName:s")) != NULL)
            yd->exchange = sdsnew(aux->valuestring);
        if ((aux = cJSON_Select(meta,".currency:s")) != NULL)
            yd->csym = sdsnew(aux->valuestring);

        /* Certain times tha Yahoo API is unable to return actual info
         * from a stock, even if it returns success. */
        if (yd->regchange == NULL) goto fmterr;
    } else {
        cJSON *meta = cJSON_Select(json,".chart.result[0].meta");
        cJSON *aux;
        if (meta == NULL) goto fmterr;
        if ((aux = cJSON_Select(meta,".symbol:s")) != NULL)
            yd->symbol = sdsnew(aux->valuestring);
        cJSON *data = cJSON_Select(json,
            ".chart.result[0].indicators.quote[0].close:a");
        if (data == NULL) goto fmterr;

        /* Count the items, so that we can size our timestamp array. */
        int len = 0;
        aux = data->child;
        while(aux != NULL) {
            len++;
            aux = aux->next;
        }
        yd->ts_len = len;
        yd->ts_data = malloc(sizeof(float)*len);

        /* Load data into array. */
        int idx = 0;
        aux = data->child;
        while(aux != NULL) {
            float v = aux->valuedouble;
            if (cJSON_IsNumber(aux))
                yd->ts_data[idx] = v;
            else
                yd->ts_data[idx] = 0;
            if (idx == 0 || v < yd->ts_min) yd->ts_min = v;
            if (idx == 0 || v > yd->ts_max) yd->ts_max = v;
            idx++;
            aux = aux->next;
        }
    }

    cJSON_Delete(json);
    return yd;

fmterr:
    cJSON_Delete(json);
    freeYahooData(yd);
    return NULL;
}

// Assembly:
subq $0xc8, %rsp
movl %edi, 0xbc(%rsp)
movq %rsi, 0xb0(%rsp)
movq %rdx, 0xa8(%rsp)
movq %rcx, 0xa0(%rsp)
movl %r8d, 0x9c(%rsp)
leaq 0x84e0(%rip), %rax      # 0x15715
movq %rax, 0x90(%rsp)
cmpl $0x1, 0xbc(%rsp)
jne 0xd2cc
movq 0x90(%rsp), %rdi
callq 0x8630
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
leaq 0x84c7(%rip), %rsi      # 0x15736
callq 0x9350
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
movq 0xb0(%rsp), %rsi
callq 0x9350
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
movq 0xa8(%rsp), %rdx
movq 0xa0(%rsp), %rcx
leaq 0x8491(%rip), %rsi      # 0x15749
movb $0x0, %al
callq 0x98c0
movq %rax, 0x88(%rsp)
jmp 0xd361
cmpl $0x0, 0xbc(%rsp)
je 0xd2e0
cmpl $0x2, 0xbc(%rsp)
jne 0xd34e
movq 0x90(%rsp), %rdi
callq 0x8630
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
leaq 0x8432(%rip), %rsi      # 0x15736
callq 0x9350
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
movq 0xb0(%rsp), %rsi
callq 0x9350
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
leaq 0x8437(%rip), %rsi      # 0x15774
movb $0x0, %al
callq 0x98c0
movq %rax, 0x88(%rsp)
jmp 0xd35f
movq $0x0, 0xc0(%rsp)
jmp 0xd91e
jmp 0xd361
movl $0x0, 0x84(%rsp)
movl $0x5, 0x80(%rsp)
movl $0x0, 0x7c(%rsp)
cmpl $0x0, 0x9c(%rsp)
je 0xd3a6
cmpl $0x0, 0xdf40(%rip)      # 0x1b2d0
je 0xd3a6
movq 0x88(%rsp), %rdi
callq 0xd930
movq %rax, 0x8(%rsp)
jmp 0xd3af
xorl %eax, %eax
movq %rax, 0x8(%rsp)
jmp 0xd3af
movq 0x8(%rsp), %rax
movq %rax, 0x70(%rsp)
cmpq $0x0, 0x70(%rsp)
setne %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x6c(%rsp)
cmpq $0x0, 0x70(%rsp)
jne 0xd44b
jmp 0xd3d5
movl 0x84(%rsp), %ecx
xorl %eax, %eax
cmpl 0x80(%rsp), %ecx
movb %al, 0x7(%rsp)
jge 0xd3f7
cmpl $0x0, 0x7c(%rsp)
sete %al
movb %al, 0x7(%rsp)
movb 0x7(%rsp), %al
testb $0x1, %al
jne 0xd401
jmp 0xd449
cmpl $0x0, 0x84(%rsp)
jle 0xd415
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x2330
movq 0x70(%rsp), %rdi
callq 0x8750
movq 0x88(%rsp), %rdi
leaq 0x7c(%rsp), %rsi
callq 0xcd80
movq %rax, 0x70(%rsp)
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0xd3d5
jmp 0xd472
cmpl $0x0, 0xde5e(%rip)      # 0x1b2b0
je 0xd46a
movq 0x88(%rsp), %rsi
leaq 0x831e(%rip), %rdi      # 0x15781
movb $0x0, %al
callq 0x2030
movl $0x1, 0x7c(%rsp)
cmpl $0x0, 0x9c(%rsp)
je 0xd4a6
cmpl $0x0, 0xde4d(%rip)      # 0x1b2d0
je 0xd4a6
cmpl $0x0, 0x6c(%rsp)
jne 0xd4a6
movq 0x88(%rsp), %rdi
movq 0x70(%rsp), %rsi
movslq 0x9c(%rsp), %rdx
callq 0xd9f0
movq 0x88(%rsp), %rdi
callq 0x8750
cmpl $0x1, 0x7c(%rsp)
je 0xd4d5
movq 0x70(%rsp), %rdi
callq 0x8750
movq $0x0, 0xc0(%rsp)
jmp 0xd91e
movl $0xf8, %edi
callq 0x2430
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rdi
xorl %esi, %esi
movl $0xf8, %edx
callq 0x2120
movl 0xbc(%rsp), %ecx
movq 0x60(%rsp), %rax
movl %ecx, (%rax)
movq 0x70(%rsp), %rdi
callq 0x3680
movq %rax, 0x58(%rsp)
movq 0x70(%rsp), %rdi
callq 0x8750
cmpl $0x0, 0xbc(%rsp)
je 0xd534
cmpl $0x2, 0xbc(%rsp)
jne 0xd707
movq 0x58(%rsp), %rdi
leaq 0x825d(%rip), %rsi      # 0x1579d
movb $0x0, %al
callq 0xb970
movq %rax, 0x50(%rsp)
cmpq $0x0, 0x50(%rsp)
jne 0xd559
jmp 0xd8fe
movq 0x50(%rsp), %rdi
leaq 0x824e(%rip), %rsi      # 0x157b3
movb $0x0, %al
callq 0xb970
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0xd591
movq 0x48(%rsp), %rax
movq 0x20(%rax), %rdi
callq 0x8630
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x50(%rsp), %rdi
leaq 0x8220(%rip), %rsi      # 0x157bd
movb $0x0, %al
callq 0xb970
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0xd5c7
movq 0x48(%rsp), %rax
movsd 0x30(%rax), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x60(%rsp), %rax
movss %xmm0, 0x20(%rax)
movq 0x50(%rsp), %rdi
leaq 0x8200(%rip), %rsi      # 0x157d3
movb $0x0, %al
callq 0xb970
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0xd649
movq 0x48(%rsp), %rax
movsd 0x30(%rax), %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0x60(%rsp), %rax
movss 0x20(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
subsd 0x40(%rsp), %xmm0
divsd 0x40(%rsp), %xmm0
movsd 0x7f69(%rip), %xmm1     # 0x15580
mulsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
callq 0x8610
movq %rax, %rdi
movsd 0x38(%rsp), %xmm0
leaq 0x81b3(%rip), %rsi      # 0x157e9
movb $0x1, %al
callq 0x98c0
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x58(%rax)
movq 0x50(%rsp), %rdi
leaq 0x815e(%rip), %rsi      # 0x157b3
movb $0x0, %al
callq 0xb970
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0xd681
movq 0x48(%rsp), %rax
movq 0x20(%rax), %rdi
callq 0x8630
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x50(%rsp), %rdi
leaq 0x8164(%rip), %rsi      # 0x157f1
movb $0x0, %al
callq 0xb970
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0xd6b9
movq 0x48(%rsp), %rax
movq 0x20(%rax), %rdi
callq 0x8630
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x60(%rax)
movq 0x50(%rsp), %rdi
leaq 0x813c(%rip), %rsi      # 0x15801
movb $0x0, %al
callq 0xb970
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0xd6f1
movq 0x48(%rsp), %rax
movq 0x20(%rax), %rdi
callq 0x8630
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x70(%rax)
movq 0x60(%rsp), %rax
cmpq $0x0, 0x58(%rax)
jne 0xd702
jmp 0xd8fe
jmp 0xd8e5
movq 0x58(%rsp), %rdi
leaq 0x808a(%rip), %rsi      # 0x1579d
movb $0x0, %al
callq 0xb970
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
jne 0xd72c
jmp 0xd8fe
movq 0x30(%rsp), %rdi
leaq 0x807b(%rip), %rsi      # 0x157b3
movb $0x0, %al
callq 0xb970
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0xd764
movq 0x28(%rsp), %rax
movq 0x20(%rax), %rdi
callq 0x8630
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x58(%rsp), %rdi
leaq 0x809d(%rip), %rsi      # 0x1580d
movb $0x0, %al
callq 0xb970
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x20(%rsp)
jne 0xd789
jmp 0xd8fe
movl $0x0, 0x1c(%rsp)
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
je 0xd7c1
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
movq 0x28(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x28(%rsp)
jmp 0xd79f
movl 0x1c(%rsp), %ecx
movq 0x60(%rsp), %rax
movl %ecx, 0x78(%rax)
movslq 0x1c(%rsp), %rdi
shlq $0x2, %rdi
callq 0x2430
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x80(%rax)
movl $0x0, 0x18(%rsp)
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
je 0xd8e3
movq 0x28(%rsp), %rax
movsd 0x30(%rax), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x14(%rsp)
movq 0x28(%rsp), %rdi
callq 0x2b10
cmpl $0x0, %eax
je 0xd84d
movss 0x14(%rsp), %xmm0
movq 0x60(%rsp), %rax
movq 0x80(%rax), %rax
movslq 0x18(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
jmp 0xd866
movq 0x60(%rsp), %rax
movq 0x80(%rax), %rax
movslq 0x18(%rsp), %rcx
xorps %xmm0, %xmm0
movss %xmm0, (%rax,%rcx,4)
cmpl $0x0, 0x18(%rsp)
je 0xd885
movss 0x14(%rsp), %xmm1
movq 0x60(%rsp), %rax
movss 0x88(%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0xd898
movss 0x14(%rsp), %xmm0
movq 0x60(%rsp), %rax
movss %xmm0, 0x88(%rax)
cmpl $0x0, 0x18(%rsp)
je 0xd8b3
movss 0x14(%rsp), %xmm0
movq 0x60(%rsp), %rax
ucomiss 0x8c(%rax), %xmm0
jbe 0xd8c6
movss 0x14(%rsp), %xmm0
movq 0x60(%rsp), %rax
movss %xmm0, 0x8c(%rax)
movl 0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18(%rsp)
movq 0x28(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x28(%rsp)
jmp 0xd800
jmp 0xd8e5
movq 0x58(%rsp), %rdi
callq 0x2c50
movq 0x60(%rsp), %rax
movq %rax, 0xc0(%rsp)
jmp 0xd91e
movq 0x58(%rsp), %rdi
callq 0x2c50
movq 0x60(%rsp), %rdi
callq 0xd130
movq $0x0, 0xc0(%rsp)
movq 0xc0(%rsp), %rax
addq $0xc8, %rsp
retq
nop