/**
 * @file    config_persist.c
 * @brief   Remembering one setting across runs with on_config_load and
 *          on_config_save. A reading aid for the tutorial page
 *          "config-persistence", not a complete plugin: the two callbacks
 *          would be assigned to IcPlugin::on_config_load / on_config_save.
 *
 * @note    Kept ASCII-only on purpose and C89 so it passes the syntax-only
 *          guard. Only the key "note" is understood; every other key that
 *          shows up is kept and written back, so downgrading or a hand-edited
 *          config.ini never loses data (the save output REPLACES the whole
 *          [Plugin.<name>] section).
 */

#include <stdio.h>
#include <string.h>

#include "nexus_plugin_api.h"

/** @brief The setting this sample understands; empty until loaded. */
static char s_note[64] = "";

/** @brief Keys this sample does not understand, kept verbatim ("key=value\n" lines). */
static char s_extra[1024] = "";

/**
 * @brief  Receives one key=value pair from the [Plugin.<name>] section.
 * @param[in] ctx   Main mount context (unused).
 * @param[in] key   Key, leading and trailing blanks already trimmed.
 * @param[in] value Value, trimmed the same way.
 * @note   UI Thread, after init() and before probe(). Only the primary
 *         mount (slaves[0]) receives it. The same key is delivered once.
 */
void NX_CALL cfg_load(NxPluginCtx ctx, const char *key, const char *value)
{
    size_t used;
    size_t need;

    NX_UNUSED_ARG(ctx);
    if (strcmp(key, "note") == 0)
    {
        used = strlen(value);
        if (used > sizeof(s_note) - 1)
        {
            used = sizeof(s_note) - 1;
        }
        memcpy(s_note, value, used);
        s_note[used] = '\0';
        return;
    }
    /* Unknown key: remember it so on_config_save can echo it back. */
    used = strlen(s_extra);
    need = strlen(key) + strlen(value) + 2;
    if (used + need < sizeof(s_extra))
    {
        sprintf(s_extra + used, "%s=%s\n", key, value);
    }
}

/**
 * @brief  Fills buf with the COMPLETE set of settings to remember.
 * @param[in]  ctx      Main mount context (unused).
 * @param[out] buf      Output buffer, already an empty string.
 * @param[in]  buf_size Always NX_PLUGIN_CONFIG_MAX (4096, NUL included).
 * @return ERR_OK when buf holds the full settings; any other value means
 *         "do not save this time, keep what was saved before".
 * @note   UI Thread, before unload and before the host writes config.ini
 *         at exit. Must be fast; ExecSync is not available here.
 *         Every line must be key=value with no control characters and no
 *         comment lines; the whole text must be at most 4094 bytes.
 */
NxLong NX_CALL cfg_save(NxPluginCtx ctx, char *buf, int buf_size)
{
    char   line[96];
    size_t len_line;
    size_t len_extra;

    NX_UNUSED_ARG(ctx);
    sprintf(line, "note=%s\n", s_note);
    len_line  = strlen(line);
    len_extra = strlen(s_extra);
    if ((int)(len_line + len_extra) > buf_size - 2)
    {
        return ERR_BUFFER_TOO_SMALL;         /* better an error than half an output */
    }
    memcpy(buf, line, len_line);
    memcpy(buf + len_line, s_extra, len_extra + 1);   /* +1 copies the NUL */
    return ERR_OK;
}
