#define _POSIX_C_SOURCE 200809L

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

static int append_text(char** buf, size_t* cap, size_t* used, const char* s, size_t len) {
    if (!buf || !cap || !used || !s) return -1;
    if (*used + len + 1U > *cap) {
        size_t next = *cap;
        while (*used + len + 1U > next) {
            next = (next == 0U) ? 256U : (next * 2U);
        }
        char* grown = (char*)realloc(*buf, next);
        if (!grown) return -1;
        *buf = grown;
        *cap = next;
    }
    memcpy(*buf + *used, s, len);
    *used += len;
    (*buf)[*used] = '\0';
    return 0;
}

char* context_bump_headings(const char* text) {
    if (!text) return NULL;

    size_t cap = strlen(text) + 256; // Initial guess
    size_t used = 0;
    char* buf = (char*)malloc(cap);
    if (!buf) return NULL;
    buf[0] = '\0';

    const char* p = text;
    while (*p) {
        const char* eol = strchr(p, '\n');
        size_t line_len = eol ? (size_t)(eol - p) : strlen(p);

        // Check if line starts with '#'
        if (line_len > 0 && p[0] == '#') {
            // Add an extra '#'
            if (append_text(&buf, &cap, &used, "#", 1) != 0) {
                free(buf);
                return NULL;
            }
        }

        // Append the rest of the line
        if (append_text(&buf, &cap, &used, p, line_len) != 0) {
            free(buf);
            return NULL;
        }

        if (eol) {
            if (append_text(&buf, &cap, &used, "\n", 1) != 0) {
                free(buf);
                return NULL;
            }
            p = eol + 1;
        } else {
            break;
        }
    }

    return buf;
}

char* context_build_title(tools_context_t* ctx) {
    if (!ctx || !ctx->cfg) return strdup("# Didactyl Agent\n\n");

    const char* name = "Didactyl Agent";
    
    // Try to get name from kind 0 profile if available
    if (ctx->template_skill_lookup) {
        // We don't have direct access to the parsed kind 0 here easily,
        // but we can try to extract it from the agent_profile tool output
        // if we really wanted to. For now, let's stick to a simple default
        // or use the config if it has a name field (it doesn't currently).
        // A more robust way would be to parse the kind 0 JSON here.
    }

    // For now, just use a generic title. The identity skill will provide the rest.
    char title[256];
    snprintf(title, sizeof(title), "# %s\n\n", name);
    return strdup(title);
}
