/*
 * sa - wrapper C do gerenciador SA.
 *
 * Mantém o binário operacional legado em sa.bin e encaminha a API de
 * contexto (--ctx-*) para sa-ctx, também implementado em C.
 */
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <sys/wait.h>

static int arg_exato(const char *a, const char *b) { return a && strcmp(a, b) == 0; }
static int arg_prefixo(const char *a, const char *p) { return a && strncmp(a, p, strlen(p)) == 0; }

static int resolver_dir(char *out, size_t tam)
{
    char exe[PATH_MAX];
    ssize_t n = readlink("/proc/self/exe", exe, sizeof(exe) - 1);
    if (n <= 0) return -1;
    exe[n] = '\0';
    char *slash = strrchr(exe, '/');
    if (!slash) return -1;
    *slash = '\0';
    if (strlen(exe) + 1 > tam) return -1;
    snprintf(out, tam, "%s", exe);
    return 0;
}

static int eh_ctx_arg(const char *a)
{
    return arg_prefixo(a, "--ctx-") ||
           arg_prefixo(a, "--origem=") ||
           arg_prefixo(a, "--max-itens=") ||
           arg_prefixo(a, "--max-bytes=") ||
           arg_exato(a, "--include-ra") ||
           arg_exato(a, "--sem-ra") ||
           arg_prefixo(a, "--formato=");
}

static int eh_ajuda_ctx(const char *a)
{
    return arg_exato(a, "--ajuda:ctx") || arg_exato(a, "--ajuda=ctx") ||
           arg_exato(a, "--ajuda:contexto") || arg_exato(a, "--ajuda=contexto") ||
           arg_exato(a, "--help:ctx") || arg_exato(a, "--help=ctx") ||
           arg_exato(a, "--help:contexto") || arg_exato(a, "--help=contexto");
}

static int eh_ajuda_geral(const char *a)
{
    return arg_exato(a, "--ajuda") || arg_exato(a, "--help") || arg_exato(a, "-h");
}

static void imprimir_ajuda_ctx(void)
{
    fputs(
        "\n10) API de contexto para sistema/LLM [contexto ctx llm indice extrair validar]\n"
        "  Normalização de fontes:\n"
        "    <sistema>/arvores      = árvores SA do sistema alvo\n"
        "    <sistema>/relspec      = relatórios SA derivados de specs\n"
        "    sisc/arvores           = contexto da ferramenta SISC\n"
        "\n"
        "  --ctx-fontes                  Lista fontes normalizadas de contexto em JSON\n"
        "  --ctx-indice                  Exporta índice JSON de itens SA com origem, arquivo, id, caminho, ra, gc, mm e metadados de confiança\n"
        "  --ctx-buscar=<texto>          Busca/rankeia itens SA para consumo de máquina\n"
        "  --ctx-extrair=<texto>         Extrai contexto compacto para LLM, com mapa hierárquico e ra resumido; use --json para saída estruturada\n"
        "  --ctx-item=<id>               Retorna item específico; com --sa=<arvore> restringe a árvore\n"
        "  --ctx-validar                 Valida árvores, relações, itens, ra e integridade; informa atualização, checksum RA e status validado/aprovado\n"
        "  --ctx-atualizar-indice        Grava cache .indice-contexto.json para consumo rápido do sistema\n"
        "  --origem=auto|sistema|ferramenta\n"
        "                                Filtra fontes; padrão auto\n"
        "  --max-itens=N --max-bytes=N   Limites para busca/extração\n"
        "  --include-ra                  Inclui trechos seguros e resumidos dos arquivos ra na extração textual\n"
        "  --sem-ra                      Não inclui conteúdo de ra (padrão)\n"
        "\n"
        "  Exemplos:\n"
        "    pp --sa --ctx-fontes\n"
        "    pp --sa --ctx-indice --origem=sistema\n"
        "    pp --sa --ctx-buscar='checkout pix cliente' --max-itens=20\n"
        "    pp --sa --ctx-extrair='checkout pix cliente' --max-bytes=60000 --include-ra\n"
        "    pp --sa=operador-manual-conector --ctx-item=2.1\n"
        "    pp --sa --ctx-validar --origem=auto\n"
        "    pp --sa --ctx-atualizar-indice --origem=sistema\n",
        stdout);
}

static int executar_e_aguardar(char *const args[])
{
    pid_t pid = fork();
    if (pid < 0) { perror("sa: fork"); return 1; }
    if (pid == 0) {
        execv(args[0], args);
        perror("sa: execv");
        _exit(127);
    }
    int st = 0;
    if (waitpid(pid, &st, 0) < 0) { perror("sa: waitpid"); return 1; }
    if (WIFEXITED(st)) return WEXITSTATUS(st);
    if (WIFSIGNALED(st)) return 128 + WTERMSIG(st);
    return 1;
}

static int exec_comando(const char *bin, int argc, char **argv)
{
    char **args = calloc((size_t)argc + 1, sizeof(char *));
    if (!args) return 1;
    args[0] = (char *)bin;
    for (int i = 1; i < argc; i++) args[i] = argv[i];
    args[argc] = NULL;
    execv(bin, args);
    perror("sa: execv");
    free(args);
    return 127;
}

int main(int argc, char **argv)
{
    char dir[PATH_MAX];
    if (resolver_dir(dir, sizeof(dir)) != 0) {
        fprintf(stderr, "sa: não foi possível localizar diretório do comando\n");
        return 1;
    }

    int tem_ctx = 0, ajuda_ctx = 0, ajuda_geral = 0;
    for (int i = 1; i < argc; i++) {
        if (eh_ctx_arg(argv[i])) tem_ctx = 1;
        if (eh_ajuda_ctx(argv[i])) ajuda_ctx = 1;
        if (eh_ajuda_geral(argv[i])) ajuda_geral = 1;
    }

    if (ajuda_ctx) { imprimir_ajuda_ctx(); return 0; }

    char alvo[PATH_MAX * 2];
    if (tem_ctx) {
        snprintf(alvo, sizeof(alvo), "%s/sa-ctx", dir);
        return exec_comando(alvo, argc, argv);
    }

    snprintf(alvo, sizeof(alvo), "%s/sa.bin", dir);
    if (ajuda_geral) {
        char *args[3];
        args[0] = alvo;
        args[1] = "--ajuda";
        args[2] = NULL;
        int rc = executar_e_aguardar(args);
        imprimir_ajuda_ctx();
        return rc;
    }

    return exec_comando(alvo, argc, argv);
}
