/**
 * @file hal_json.c
 * @brief HAL JSON 解析与构建实现（JieLi 平台）
 */

#include "hal_json.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define JSON_MAX_KEYS   32
#define JSON_BUF_SIZE   1024

typedef struct {
    char *data;         /* 已解析或已构建JSON的副本 */
    int   data_len;
    /* Builder 状态 */
    char *build_buf;
    int   build_len;
    int   build_cap;
    int   key_count;
    bool  is_builder;
    /* 字符串提取缓冲区 */
    char *str_buf;
    int   str_buf_cap;
} hal_json_impl_t;

/* --- Internal helpers --- */

static const char *find_key(const char *json, int json_len, const char *key)
{
    if (!json || !key) {
        return NULL;
    }
    int key_len = strlen(key);
    const char *p = json;
    const char *end = json + json_len;

    while (p < end) {
        /* 查找 key 的起始引号 */
        p = memchr(p, '"', end - p);
        if (!p) {
            return NULL;
        }
        p++; /* 跳过起始引号 */
        if ((end - p) >= key_len && memcmp(p, key, key_len) == 0 && p[key_len] == '"') {
            /* 命中 key，跳到值 */
            p += key_len + 1; /* 跳过 key 和结束引号 */
            /* 跳过冒号和空白 */
            while (p < end && (*p == ':' || *p == ' ' || *p == '\t')) {
                p++;
            }
            return p;
        }
        /* 跳到本字符串末尾 */
        while (p < end && *p != '"') {
            if (*p == '\\') {
                p++; /* 跳过转义字符 */
            }
            p++;
        }
        if (p < end) {
            p++; /* 跳过结束引号 */
        }
    }
    return NULL;
}

static int extract_string_value(const char *p, const char *end, char *out, int out_size)
{
    if (!p || *p != '"') {
        return -1;
    }
    p++; /* 跳过起始引号 */
    int i = 0;
    while (p < end && *p != '"' && i < out_size - 1) {
        if (*p == '\\') {
            p++;
            if (p >= end) {
                break;
            }
            switch (*p) {
            case 'n':
                out[i++] = '\n';
                break;
            case 't':
                out[i++] = '\t';
                break;
            case '"':
                out[i++] = '"';
                break;
            case '\\':
                out[i++] = '\\';
                break;
            default:
                out[i++] = *p;
                break;
            }
        } else {
            out[i++] = *p;
        }
        p++;
    }
    out[i] = '\0';
    return i;
}

/* --- Public API --- */

hal_json_t hal_json_parse(const char *text)
{
    if (!text) {
        return NULL;
    }

    int len = strlen(text);
    hal_json_impl_t *j = (hal_json_impl_t *)zalloc(sizeof(hal_json_impl_t));
    if (!j) {
        return NULL;
    }

    j->data = (char *)malloc(len + 1);
    if (!j->data) {
        free(j);
        return NULL;
    }
    memcpy(j->data, text, len + 1);
    j->data_len = len;
    j->is_builder = false;

    return (hal_json_t)j;
}

hal_json_t hal_json_create_object(void)
{
    hal_json_impl_t *j = (hal_json_impl_t *)zalloc(sizeof(hal_json_impl_t));
    if (!j) {
        return NULL;
    }

    j->build_cap = JSON_BUF_SIZE;
    j->build_buf = (char *)malloc(j->build_cap);
    if (!j->build_buf) {
        free(j);
        return NULL;
    }
    j->build_buf[0] = '{';
    j->build_len = 1;
    j->key_count = 0;
    j->is_builder = true;

    return (hal_json_t)j;
}

const char *hal_json_get_string(hal_json_t json, const char *key)
{
    if (!json || !key) {
        return NULL;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (j->is_builder || !j->data) {
        return NULL;
    }

    const char *val = find_key(j->data, j->data_len, key);
    if (!val || *val != '"') {
        return NULL;
    }

    /* 找到字符串结束位置（跳过转义字符），不修改原始缓冲区 */
    const char *start = val + 1;
    const char *p = start;
    const char *end = j->data + j->data_len;
    while (p < end && *p != '"') {
        if (*p == '\\') {
            p++;
        }
        p++;
    }

    /* 计算反转义后所需空间（不会超过原始长度） */
    int raw_len = (int)(p - start);
    int need = raw_len + 1;

    /* 确保字符串缓冲区足够大 */
    if (!j->str_buf || j->str_buf_cap < need) {
        if (j->str_buf) {
            free(j->str_buf);
        }
        j->str_buf_cap = need < 128 ? 128 : need;
        j->str_buf = (char *)malloc(j->str_buf_cap);
        if (!j->str_buf) {
            j->str_buf_cap = 0;
            return NULL;
        }
    }

    /* 将反转义后的内容写入字符串缓冲区 */
    const char *r = start;
    char *w = j->str_buf;
    while (r < p) {
        if (*r == '\\') {
            r++;
            if (r >= p) {
                break;
            }
            switch (*r) {
            case '"':
                *w++ = '"';
                break;
            case '\\':
                *w++ = '\\';
                break;
            case 'n':
                *w++ = '\n';
                break;
            case 't':
                *w++ = '\t';
                break;
            case '/':
                *w++ = '/';
                break;
            default:
                *w++ = *r;
                break;
            }
        } else {
            *w++ = *r;
        }
        r++;
    }
    *w = '\0';
    return j->str_buf;
}

int hal_json_get_int(hal_json_t json, const char *key, int *out_value)
{
    if (!json || !key || !out_value) {
        return -1;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (j->is_builder || !j->data) {
        return -1;
    }

    const char *val = find_key(j->data, j->data_len, key);
    if (!val) {
        return -1;
    }

    /* 处理带引号的数字 */
    if (*val == '"') {
        val++;
    }
    *out_value = atoi(val);
    return 0;
}

int hal_json_get_number_string(hal_json_t json, const char *key,
                               char *out, size_t out_size)
{
    if (!json || !key || !out || out_size == 0) {
        return -1;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (j->is_builder || !j->data) {
        return -1;
    }

    const char *val = find_key(j->data, j->data_len, key);
    if (!val) {
        return -1;
    }
    if (*val == '"') {
        val++;
    }

    size_t i = 0;
    while (*val >= '0' && *val <= '9' && i + 1 < out_size) {
        out[i++] = *val++;
    }
    out[i] = '\0';
    return (i > 0) ? (int)i : -1;
}

int hal_json_get_bool(hal_json_t json, const char *key, bool *out_value)
{
    if (!json || !key || !out_value) {
        return -1;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (j->is_builder || !j->data) {
        return -1;
    }

    const char *val = find_key(j->data, j->data_len, key);
    if (!val) {
        return -1;
    }

    *out_value = (*val == 't' || *val == 'T' || *val == '1');
    return 0;
}

static int builder_ensure_space(hal_json_impl_t *j, int need)
{
    if (j->build_len + need >= j->build_cap) {
        int new_cap = j->build_cap * 2;
        while (j->build_len + need >= new_cap) {
            new_cap *= 2;
        }
        char *new_buf = (char *)realloc(j->build_buf, new_cap);
        if (!new_buf) {
            return -1;
        }
        j->build_buf = new_buf;
        j->build_cap = new_cap;
    }
    return 0;
}

int hal_json_add_string(hal_json_t json, const char *key, const char *value)
{
    if (!json || !key || !value) {
        return -1;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (!j->is_builder) {
        return -1;
    }

    int need = strlen(key) + strlen(value) + 8; /* quotes, colon, comma */
    if (builder_ensure_space(j, need) < 0) {
        return -1;
    }

    int n = 0;
    if (j->key_count > 0) {
        n = snprintf(j->build_buf + j->build_len, j->build_cap - j->build_len,
                     ",\"%s\":\"%s\"", key, value);
    } else {
        n = snprintf(j->build_buf + j->build_len, j->build_cap - j->build_len,
                     "\"%s\":\"%s\"", key, value);
    }
    j->build_len += n;
    j->key_count++;
    return 0;
}

int hal_json_add_int(hal_json_t json, const char *key, int value)
{
    if (!json || !key) {
        return -1;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (!j->is_builder) {
        return -1;
    }

    int need = strlen(key) + 20;
    if (builder_ensure_space(j, need) < 0) {
        return -1;
    }

    int n = 0;
    if (j->key_count > 0) {
        n = snprintf(j->build_buf + j->build_len, j->build_cap - j->build_len,
                     ",\"%s\":%d", key, value);
    } else {
        n = snprintf(j->build_buf + j->build_len, j->build_cap - j->build_len,
                     "\"%s\":%d", key, value);
    }
    j->build_len += n;
    j->key_count++;
    return 0;
}

int hal_json_add_bool(hal_json_t json, const char *key, bool value)
{
    if (!json || !key) {
        return -1;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (!j->is_builder) {
        return -1;
    }

    int need = strlen(key) + 12;
    if (builder_ensure_space(j, need) < 0) {
        return -1;
    }

    int n = 0;
    if (j->key_count > 0) {
        n = snprintf(j->build_buf + j->build_len, j->build_cap - j->build_len,
                     ",\"%s\":%s", key, value ? "true" : "false");
    } else {
        n = snprintf(j->build_buf + j->build_len, j->build_cap - j->build_len,
                     "\"%s\":%s", key, value ? "true" : "false");
    }
    j->build_len += n;
    j->key_count++;
    return 0;
}

/**
 * @brief 跳过一个完整的JSON值（字符串/数字/对象/数组/布尔/null）
 *
 * @return 值结尾之后的位置, NULL表示解析失败
 */
static const char *skip_json_value(const char *p, const char *end)
{
    if (!p || p >= end) {
        return NULL;
    }

    /* 跳过空白 */
    while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) {
        p++;
    }

    if (p >= end) {
        return NULL;
    }

    if (*p == '"') {
        /* 字符串: 跳到闭合引号 */
        p++;
        while (p < end && *p != '"') {
            if (*p == '\\') p++;
            p++;
        }
        return (p < end) ? p + 1 : NULL;
    } else if (*p == '{') {
        /* 对象: 匹配大括号 */
        int depth = 1;
        p++;
        while (p < end && depth > 0) {
            if (*p == '"') {
                p++;
                while (p < end && *p != '"') {
                    if (*p == '\\') p++;
                    p++;
                }
            } else if (*p == '{') {
                depth++;
            } else if (*p == '}') {
                depth--;
            }
            p++;
        }
        return p;
    } else if (*p == '[') {
        /* 数组: 匹配方括号 */
        int depth = 1;
        p++;
        while (p < end && depth > 0) {
            if (*p == '"') {
                p++;
                while (p < end && *p != '"') {
                    if (*p == '\\') p++;
                    p++;
                }
            } else if (*p == '[') {
                depth++;
            } else if (*p == ']') {
                depth--;
            }
            p++;
        }
        return p;
    } else {
        /* 数字/布尔/null: 跳到分隔符 */
        while (p < end && *p != ',' && *p != '}' && *p != ']' &&
               *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r') {
            p++;
        }
        return p;
    }
}

hal_json_t hal_json_get_object(hal_json_t json, const char *key)
{
    if (!json || !key) {
        return NULL;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (j->is_builder || !j->data) {
        return NULL;
    }

    const char *val = find_key(j->data, j->data_len, key);
    if (!val || *val != '{') {
        return NULL;
    }

    /* 找到配对的 '}' */
    const char *obj_end = skip_json_value(val, j->data + j->data_len);
    if (!obj_end) {
        return NULL;
    }

    int obj_len = (int)(obj_end - val);

    /* 创建新的JSON对象（拷贝子串） */
    hal_json_impl_t *child = (hal_json_impl_t *)zalloc(sizeof(hal_json_impl_t));
    if (!child) {
        return NULL;
    }
    child->data = (char *)malloc(obj_len + 1);
    if (!child->data) {
        free(child);
        return NULL;
    }
    memcpy(child->data, val, obj_len);
    child->data[obj_len] = '\0';
    child->data_len = obj_len;
    child->is_builder = false;

    return (hal_json_t)child;
}

hal_json_t hal_json_get_array(hal_json_t json, const char *key)
{
    if (!json || !key) {
        return NULL;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;
    if (j->is_builder || !j->data) {
        return NULL;
    }

    const char *val = find_key(j->data, j->data_len, key);
    if (!val || *val != '[') {
        return NULL;
    }

    /* 找到配对的 ']' */
    const char *arr_end = skip_json_value(val, j->data + j->data_len);
    if (!arr_end) {
        return NULL;
    }

    int arr_len = (int)(arr_end - val);

    /* 创建新的JSON对象保存数组片段 */
    hal_json_impl_t *arr = (hal_json_impl_t *)zalloc(sizeof(hal_json_impl_t));
    if (!arr) {
        return NULL;
    }
    arr->data = (char *)malloc(arr_len + 1);
    if (!arr->data) {
        free(arr);
        return NULL;
    }
    memcpy(arr->data, val, arr_len);
    arr->data[arr_len] = '\0';
    arr->data_len = arr_len;
    arr->is_builder = false;

    return (hal_json_t)arr;
}

int hal_json_get_array_size(hal_json_t array)
{
    if (!array) {
        return 0;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)array;
    if (j->is_builder || !j->data || j->data[0] != '[') {
        return 0;
    }

    const char *p = j->data + 1;
    const char *end = j->data + j->data_len;
    int count = 0;

    while (p < end) {
        /* 跳过空白 */
        while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || *p == ',')) {
            p++;
        }
        if (p >= end || *p == ']') {
            break;
        }
        count++;
        p = skip_json_value(p, end);
        if (!p) {
            break;
        }
    }

    return count;
}

hal_json_t hal_json_get_array_item(hal_json_t array, int index)
{
    if (!array || index < 0) {
        return NULL;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)array;
    if (j->is_builder || !j->data || j->data[0] != '[') {
        return NULL;
    }

    const char *p = j->data + 1;
    const char *end = j->data + j->data_len;
    int i = 0;

    while (p < end) {
        /* 跳过空白和逗号 */
        while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || *p == ',')) {
            p++;
        }
        if (p >= end || *p == ']') {
            break;
        }

        if (i == index) {
            /* 找到目标元素，提取其值 */
            const char *val_start = p;
            const char *val_end = skip_json_value(p, end);
            if (!val_end) {
                return NULL;
            }
            int val_len = (int)(val_end - val_start);

            hal_json_impl_t *item = (hal_json_impl_t *)zalloc(sizeof(hal_json_impl_t));
            if (!item) {
                return NULL;
            }
            item->data = (char *)malloc(val_len + 1);
            if (!item->data) {
                free(item);
                return NULL;
            }
            memcpy(item->data, val_start, val_len);
            item->data[val_len] = '\0';
            item->data_len = val_len;
            item->is_builder = false;

            return (hal_json_t)item;
        }

        p = skip_json_value(p, end);
        if (!p) {
            break;
        }
        i++;
    }

    return NULL;
}

const char *hal_json_to_string(hal_json_t json)
{
    if (!json) {
        return NULL;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;

    if (!j->is_builder) {
        return j->data;
    }

    /* 结束对象 */
    if (builder_ensure_space(j, 2) < 0) {
        return NULL;
    }
    j->build_buf[j->build_len++] = '}';
    j->build_buf[j->build_len] = '\0';
    return j->build_buf;
}

void hal_json_destroy(hal_json_t json)
{
    if (!json) {
        return;
    }
    hal_json_impl_t *j = (hal_json_impl_t *)json;

    if (j->data) {
        free(j->data);
    }
    if (j->build_buf) {
        free(j->build_buf);
    }
    if (j->str_buf) {
        free(j->str_buf);
    }
    free(j);
}
