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

#include "n_os_tr_tui.h"

static void copy_str(char* dst, size_t dst_len, const char* src) {
    if (!dst || dst_len == 0) return;
    if (!src) {
        dst[0] = '\0';
        return;
    }
    snprintf(dst, dst_len, "%s", src);
}

static void trim(char* s) {
    size_t len;
    if (!s) return;

    while (*s && isspace((unsigned char)*s)) {
        memmove(s, s + 1, strlen(s));
    }

    len = strlen(s);
    while (len > 0 && isspace((unsigned char)s[len - 1])) {
        s[len - 1] = '\0';
        len--;
    }
}

static int parse_default(const char* v) {
    if (!v) return 0;
    if (strcmp(v, "on") == 0 || strcmp(v, "1") == 0 || strcmp(v, "true") == 0) return 1;
    return 0;
}

static void set_entry(service_entry_t* e,
                      char key,
                      const char* unit,
                      const char* label,
                      int default_on,
                      const char* deps) {
    if (!e) return;
    memset(e, 0, sizeof(*e));
    e->key = key;
    copy_str(e->unit, sizeof(e->unit), unit);
    copy_str(e->label, sizeof(e->label), label);
    e->default_on = default_on;
    copy_str(e->deps, sizeof(e->deps), deps ? deps : "-");
    e->desired_on = default_on;
}

int services_conf_load_fallback(service_entry_t* out, size_t max, size_t* out_count) {
    size_t i = 0;
    if (!out || !out_count || max < 8) return N_OS_TR_TUI_ERR;

    set_entry(&out[i++], 'r', "c-relay.service", "c-relay", 0, "nginx.service");
    set_entry(&out[i++], 'g', "ginxsom.service", "ginxsom", 0, "nginx.service");
    set_entry(&out[i++], 'f', "fips.service", "fips", 0, "-");
    set_entry(&out[i++], 'n', "nginx.service", "nginx", 0, "-");
    set_entry(&out[i++], 'l', "nostr-config-loader.service", "config-loader", 0, "-");
    set_entry(&out[i++], 'w', "nostr-config-writer.service", "config-writer", 0, "nostr-config-loader.service");
    set_entry(&out[i++], 's', "ssh.service", "ssh", 0, "-");
    set_entry(&out[i++], 't', "tor.service", "tor", 0, "-");

    *out_count = i;
    return N_OS_TR_TUI_OK;
}

int services_conf_load(const char* path, service_entry_t* out, size_t max, size_t* out_count) {
    FILE* fp;
    char line[512];
    size_t n = 0;

    if (!path || !out || !out_count || max == 0) return N_OS_TR_TUI_ERR;

    fp = fopen(path, "r");
    if (!fp) return N_OS_TR_TUI_ERR;

    while (fgets(line, sizeof(line), fp) != NULL) {
        char* tok;
        char local[512];
        char* key_s;
        char* unit_s;
        char* label_s;
        char* def_s;
        char* deps_s;
        char key;

        copy_str(local, sizeof(local), line);
        trim(local);
        if (local[0] == '\0' || local[0] == '#') continue;

        tok = strtok(local, "\t ");
        if (!tok) continue;
        key_s = tok;

        tok = strtok(NULL, "\t ");
        if (!tok) continue;
        unit_s = tok;

        tok = strtok(NULL, "\t ");
        if (!tok) continue;
        label_s = tok;

        tok = strtok(NULL, "\t ");
        if (!tok) continue;
        def_s = tok;

        tok = strtok(NULL, "\t ");
        deps_s = tok ? tok : "-";

        key = (char)tolower((unsigned char)key_s[0]);
        if (!isprint((unsigned char)key)) continue;

        if (n >= max) {
            fclose(fp);
            return N_OS_TR_TUI_ERR;
        }

        set_entry(&out[n], key, unit_s, label_s, parse_default(def_s), deps_s);
        n++;
    }

    fclose(fp);

    if (n == 0) return N_OS_TR_TUI_ERR;
    *out_count = n;
    return N_OS_TR_TUI_OK;
}
