// SPDX-License-Identifier: GPL-3.0-or-later

#include "rrdset2json.h"

// generate JSON for the /api/v1/chart API call

void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memory_used) {
    rrdset_rdlock(st);

    buffer_sprintf(wb,
            "\t\t{\n"
            "\t\t\t\"id\": \"%s\",\n"
            "\t\t\t\"name\": \"%s\",\n"
            "\t\t\t\"type\": \"%s\",\n"
            "\t\t\t\"family\": \"%s\",\n"
            "\t\t\t\"context\": \"%s\",\n"
            "\t\t\t\"title\": \"%s (%s)\",\n"
            "\t\t\t\"priority\": %ld,\n"
            "\t\t\t\"plugin\": \"%s\",\n"
            "\t\t\t\"module\": \"%s\",\n"
            "\t\t\t\"enabled\": %s,\n"
            "\t\t\t\"units\": \"%s\",\n"
            "\t\t\t\"data_url\": \"/api/v1/data?chart=%s\",\n"
            "\t\t\t\"chart_type\": \"%s\",\n"
            "\t\t\t\"duration\": %ld,\n"
            "\t\t\t\"first_entry\": %ld,\n"
            "\t\t\t\"last_entry\": %ld,\n"
            "\t\t\t\"update_every\": %d,\n"
            "\t\t\t\"dimensions\": {\n"
                   , st->id
                   , st->name
                   , st->type
                   , st->family
                   , st->context
                   , st->title, st->name
                   , st->priority
                   , st->plugin_name?st->plugin_name:""
                   , st->module_name?st->module_name:""
                   , rrdset_flag_check(st, RRDSET_FLAG_ENABLED)?"true":"false"
                   , st->units
                   , st->name
                   , rrdset_type_name(st->chart_type)
                   , st->entries * st->update_every
                   , rrdset_first_entry_t(st)
                   , rrdset_last_entry_t(st)
                   , st->update_every
    );

    unsigned long memory = st->memsize;

    size_t dimensions = 0;
    RRDDIM *rd;
    rrddim_foreach_read(rd, st) {
        if(rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN) || rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE)) continue;

        memory += rd->memsize;

        buffer_sprintf(
                wb
                , "%s"
                  "\t\t\t\t\"%s\": { \"name\": \"%s\" }"
                , dimensions ? ",\n" : ""
                , rd->id
                , rd->name
        );

        dimensions++;
    }

    if(dimensions_count) *dimensions_count += dimensions;
    if(memory_used) *memory_used += memory;

    buffer_strcat(wb, "\n\t\t\t},\n\t\t\t\"green\": ");
    buffer_rrd_value(wb, st->green);
    buffer_strcat(wb, ",\n\t\t\t\"red\": ");
    buffer_rrd_value(wb, st->red);

    buffer_strcat(wb, ",\n\t\t\t\"alarms\": {\n");
    size_t alarms = 0;
    RRDCALC *rc;
    for(rc = st->alarms; rc ; rc = rc->rrdset_next) {

        buffer_sprintf(
                wb
                , "%s"
                  "\t\t\t\t\"%s\": {\n"
                  "\t\t\t\t\t\"id\": %u,\n"
                  "\t\t\t\t\t\"status\": \"%s\",\n"
                  "\t\t\t\t\t\"units\": \"%s\",\n"
                  "\t\t\t\t\t\"update_every\": %d\n"
                  "\t\t\t\t}"
                , (alarms) ? ",\n" : ""
                , rc->name
                , rc->id
                , rrdcalc_status2string(rc->status)
                , rc->units
                , rc->update_every
        );

        alarms++;
    }

    buffer_sprintf(wb,
            "\n\t\t\t}\n\t\t}"
    );

    rrdset_unlock(st);
}
