/* criar-spec - cria spec-diretivas/spec_*.json */
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <limits.h>
#include <sys/stat.h>
#include <errno.h>
#include <time.h>
#include "../restricao.h"

#define FONTE_PREFIX "--fonte-informacao="
#define FONTE_CAMEL_PREFIX "--fonteInformacao="
#define PERFIL_PREFIX "--perfil-uso="
#define PERFIL_CAMEL_PREFIX "--perfilUso="

static void uso(void)
{
    fputs(
        "Uso:\n"
        "  pp --criar-spec=<nome> [--fonte-informacao=url1,url2] [--perfil-uso=sisc|geral]\n"
        "  pp --criar-spec --ajuda:<grupo>\n"
        "\n"
        "Descrição:\n"
        "  Cria uma spec em spec-diretivas/spec_<nome>.json no formato completo\n"
        "  diretiva-persona-agente, alinhado às specs atuais da biblioteca.\n"
        "  O arquivo gerado inclui comentariosOperador com orientação para cada item.\n"
        "\n"
        "Grupos de ajuda: uso, entrada, opcoes, arquivos, qualidade, exemplos.\n"
        "\n"
        "1) Uso e ajuda [uso ajuda]\n"
        "  --ajuda, --help, -h            Exibe esta ajuda\n"
        "  --ajuda:<grupo>                Filtra um grupo. Ex: pp --criar-spec --ajuda:opcoes\n"
        "\n"
        "2) Entrada [entrada]\n"
        "  --criar-spec=<nome>            Nome da spec; adiciona spec_ e .json quando necessário\n"
        "  nome=modelo                    Cria um modelo completo comentado para preenchimento\n"
        "\n"
        "3) Opções [opcoes]\n"
        "  --fonte-informacao=<urls>      Fontes separadas por vírgula\n"
        "  --perfil-uso=sisc|geral        Perfil da spec; padrão geral, ou sisc em siscore\n"
        "  Exemplo com todas as flags do grupo:\n"
        "    pp --criar-spec=api-rest --fonte-informacao=https://exemplo.com/docs --perfil-uso=geral\n"
        "\n"
        "4) Arquivos gerados [arquivos]\n"
        "  spec-diretivas/spec_<nome>.json\n"
        "  Inclui aplicabilidadeSisc, agente completo, materialTecnico completo,\n"
        "  sincronizacao e comentariosOperador. qualidadeSpec deve ser revisado no próprio JSON.\n"
        "\n"
        "5) Qualidade [qualidade]\n"
        "  Preencha/remova os textos TODO operador antes de considerar a spec final.\n"
        "  Depois revise/normalize com pp --normalizar-spec=<spec_arquivo.json>.\n"
        "\n"
        "6) Exemplos [exemplos]\n"
        "  pp --criar-spec=seguranca\n"
        "  pp --criar-spec=api-rest --fonte-informacao=https://exemplo.com/docs\n"
        "  pp --criar-spec=comunicacao --perfil-uso=sisc\n"
        "  pp --criar-spec=modelo\n",
        stdout);
}

static int eh_dir(const char*p){struct stat st;return stat(p,&st)==0&&S_ISDIR(st.st_mode);}
static int garantir_dir(const char*d){struct stat st;if(stat(d,&st)==0)return S_ISDIR(st.st_mode)?0:-1;return mkdir(d,0775)==0||errno==EEXIST?0:-1;}
static int juntar_path(char*out,size_t tam,const char*a,const char*b){size_t la=strlen(a),lb=strlen(b);if(la+1+lb+1>tam)return-1;memcpy(out,a,la);out[la]='/';memcpy(out+la+1,b,lb+1);return 0;}
static int validar_raiz_sistema_atual(const char*raiz){(void)raiz;return 0;}
static int termina(const char*s,const char*x){size_t a=strlen(s),b=strlen(x);return a>=b&&!strcasecmp(s+a-b,x);}
static void slug(const char*in,char*out,size_t tam){size_t j=0;for(size_t i=0;in&&in[i]&&j+1<tam;i++){unsigned char c=in[i];if(isalnum(c)||c=='.')out[j++]=(char)tolower(c);else if(c=='-'||c=='_'||isspace(c)){if(j&&out[j-1]!='_')out[j++]='_';}}while(j&&out[j-1]=='_')j--;out[j]='\0';}
static int nome_arquivo(const char*arg,char*out,size_t tam){char tmp[PATH_MAX];snprintf(tmp,sizeof(tmp),"%s",arg?arg:"");char*v=tmp;while(isspace((unsigned char)*v))v++;if(!strncmp(v,"spec-diretivas/",15))v+=15;if(!strncmp(v,"diretivas/",10))v+=10;if(strchr(v,'/')||strchr(v,'\\'))return-1;if(termina(v,".json"))v[strlen(v)-5]='\0';char s[256];slug(v,s,sizeof(s));if(!s[0])return-1;if(strncmp(s,"spec_",5)!=0)snprintf(out,tam,"spec_%s.json",s);else snprintf(out,tam,"%s.json",s);return 0;}
static void categoria(const char*arq,char*out,size_t tam){snprintf(out,tam,"%s",arq);char*p=strrchr(out,'.');if(p)*p='\0';if(!strncmp(out,"spec_",5))memmove(out,out+5,strlen(out+5)+1);}
static void titulo(const char*cat,char*out,size_t tam){snprintf(out,tam,"%s",cat);int cap=1;for(char*p=out;*p;p++){if(*p=='_'||*p=='-'){*p=' ';cap=1;}else if(cap){*p=(char)toupper((unsigned char)*p);cap=0;}}}
static void kebab_id(const char*in,char*out,size_t tam){size_t j=0;int sep=0;for(size_t i=0;in&&in[i]&&j+1<tam;i++){unsigned char c=(unsigned char)in[i];if(isalnum(c)){if(sep&&j&&j+1<tam)out[j++]='-';out[j++]=(char)tolower(c);sep=0;}else if(c=='_'||c=='-'||c=='.'||isspace(c)){sep=1;}}while(j&&out[j-1]=='-')j--;out[j]='\0';}

static char *json_escape(const char*s){size_t cap=strlen(s)*2+8,j=0;char*o=malloc(cap);if(!o)return NULL;for(const char*p=s;*p;p++){if(j+8>=cap){cap*=2;char*n=realloc(o,cap);if(!n){free(o);return NULL;}o=n;}if(*p=='"'||*p=='\\'){o[j++]='\\';o[j++]=*p;}else if(*p=='\n'){o[j++]='\\';o[j++]='n';}else if(*p=='\r'){o[j++]='\\';o[j++]='r';}else if(*p=='\t'){o[j++]='\\';o[j++]='t';}else o[j++]=*p;}o[j]='\0';return o;}
static void jstr(FILE*fp,const char*s){char*e=json_escape(s?s:"");if(!e){fputs("\"\"",fp);return;}fputc('"',fp);fputs(e,fp);fputc('"',fp);free(e);}

static void perfil_padrao(char*out,size_t tam){
    char cwd[PATH_MAX];
    snprintf(out,tam,"geral");
    if(!getcwd(cwd,sizeof(cwd)))return;
    char*base=strrchr(cwd,'/');
    base=base?base+1:cwd;
    if(!strcmp(base,"siscore"))snprintf(out,tam,"sisc");
}

static int perfil_valido(const char*v){return !strcmp(v,"sisc")||!strcmp(v,"geral");}

static void parse_fontes(const char *valor, char *out_fontes, size_t tam_fontes)
{
    char *dup = strdup(valor ? valor : "");
    if (!dup) return;
    char *save = NULL;
    char *t = strtok_r(dup, ",\t\n", &save);
    while (t) {
        while (isspace((unsigned char)*t)) t++;
        char *fim = t + strlen(t);
        while (fim > t && isspace((unsigned char)fim[-1])) *--fim = '\0';
        if (*t) {
            char *e = json_escape(t);
            if (e) {
                if (out_fontes[0]) strncat(out_fontes, ",\n        ", tam_fontes - strlen(out_fontes) - 1);
                strncat(out_fontes, "\"", tam_fontes - strlen(out_fontes) - 1);
                strncat(out_fontes, e, tam_fontes - strlen(out_fontes) - 1);
                strncat(out_fontes, "\"", tam_fontes - strlen(out_fontes) - 1);
                free(e);
            }
        }
        t = strtok_r(NULL, ",\t\n", &save);
    }
    free(dup);
}

static void parse_opcoes(int argc,char**argv,char*out_fontes,size_t tam_fontes,char*out_perfil,size_t tam_perfil){
    out_fontes[0]='\0';
    perfil_padrao(out_perfil,tam_perfil);
    for(int i=2;i<argc;i++){
        if(strncmp(argv[i],FONTE_PREFIX,strlen(FONTE_PREFIX))==0){
            parse_fontes(argv[i]+strlen(FONTE_PREFIX),out_fontes,tam_fontes);
        }else if(strncmp(argv[i],FONTE_CAMEL_PREFIX,strlen(FONTE_CAMEL_PREFIX))==0){
            parse_fontes(argv[i]+strlen(FONTE_CAMEL_PREFIX),out_fontes,tam_fontes);
        }else if(strncmp(argv[i],PERFIL_PREFIX,strlen(PERFIL_PREFIX))==0){
            snprintf(out_perfil,tam_perfil,"%s",argv[i]+strlen(PERFIL_PREFIX));
            for(char*p=out_perfil;*p;p++)*p=(char)tolower((unsigned char)*p);
            if(!perfil_valido(out_perfil)){fprintf(stderr,"criar-spec: --perfil-uso deve ser 'sisc' ou 'geral'.\n");exit(1);}
        }else if(strncmp(argv[i],PERFIL_CAMEL_PREFIX,strlen(PERFIL_CAMEL_PREFIX))==0){
            snprintf(out_perfil,tam_perfil,"%s",argv[i]+strlen(PERFIL_CAMEL_PREFIX));
            for(char*p=out_perfil;*p;p++)*p=(char)tolower((unsigned char)*p);
            if(!perfil_valido(out_perfil)){fprintf(stderr,"criar-spec: --perfilUso deve ser 'sisc' ou 'geral'.\n");exit(1);}
        }else if(!strcmp(argv[i],"--help")||!strcmp(argv[i],"--ajuda")||!strcmp(argv[i],"-h")||!strncmp(argv[i],"--ajuda:",8)||!strncmp(argv[i],"--ajuda=",8)){
            uso();
            exit(0);
        }else{
            fprintf(stderr,"criar-spec: parametro desconhecido: %s\n",argv[i]);
            exit(1);
        }
    }
}

static void emitir_comentarios(FILE *fp)
{
    static const char *linhas[] = {
        "    \"comentariosOperador\": {\n",
        "        \"tipo\": \"Use diretiva-persona-agente para specs que tambem geram ou orientam agentes derivados.\",\n",
        "        \"perfilUso\": \"Informe geral para specs reutilizaveis ou sisc para specs internas do SISC.\",\n",
        "        \"fonteUnicaDeDescobertaAgente\": \"true indica que o agente deve usar esta spec como fonte canonica para o tema.\",\n",
        "        \"fonteInformacao\": \"Liste documentos, arquivos, URLs, normas e codigo-fonte que fundamentam a spec. Troque TODO por fontes reais.\",\n",
        "        \"arquivo\": \"Caminho relativo real deste arquivo; mantenha sincronizado ao renomear.\",\n",
        "        \"llm\": \"Preset LLM usado pelo agente; atual.json e o padrao quando nao houver especializacao.\",\n",
        "        \"aplicabilidadeSisc\": {\n",
        "            \"perfilPrimario\": \"Perfis/cenarios em que a spec deve ser aplicada.\",\n",
        "            \"usarEscutaNativa\": \"Mantenha true quando a spec envolver atores SISC que se comunicam pelo espaco.\",\n",
        "            \"naoImplementarProcessoDeMensagens\": \"Mantenha true para impedir filas, brokers ou mecanismos concorrentes ao espaco SISC.\",\n",
        "            \"protocoloMensagem\": \"Nome do protocolo canonico de mensagens usado pelo SISC.\",\n",
        "            \"diretorioEspaco\": \"Diretorio base do espaco de mensagens.\",\n",
        "            \"observacao\": \"Explique como esta spec se relaciona com escuta.c, pp --api e o espaco.\",\n",
        "            \"formatoEscutaCanonico\": \"Arquivo JSON que define o layout canonico aceito pela escuta.\",\n",
        "            \"fonteDoFormatoDeMensagem\": \"Fonte que deve ser consultada antes de publicar/consumir mensagens.\",\n",
        "            \"colocacaoNoEspaco\": \"Regra operacional para colocar mensagens no espaco sem escrita direta.\",\n",
        "            \"leituraDoEspaco\": \"Regra operacional para leitura apenas por arquivo entregue pela escuta.\",\n",
        "            \"importacaoFormatoEscuta\": \"Quando e como copiar/importar o formato canonico em novos sistemas.\",\n",
        "            \"apiDeclarativaCatalogo\": \"Catalogo declarativo que mapeia mensagens para destinos SISC validos.\",\n",
        "            \"proibirAcessoDiretoEntreAtores\": \"Mantenha true para proibir chamada direta entre agentes, conectores e modulos.\",\n",
        "            \"comunicacaoEntreAtores\": \"Descreva o meio permitido de comunicacao entre atores.\",\n",
        "            \"publicacaoSomenteViaApi\": \"Mantenha true para exigir publicacao via pp --api/API declarativa.\",\n",
        "            \"validacaoPublicacaoEscuta\": \"Explique a validacao feita pela escuta antes de aceitar a mensagem.\"\n",
        "        },\n",
        "        \"agente\": {\n",
        "            \"criar\": \"true materializa agente derivado; false deixa a spec apenas como documento normativo.\",\n",
        "            \"nome\": \"Identificador estavel do agente, em kebab-case, sem espacos.\",\n",
        "            \"titulo\": \"Nome humano curto para exibicao e relatorios.\",\n",
        "            \"persona\": \"Competencia, senioridade e foco tecnico que o agente deve assumir.\",\n",
        "            \"objetivo\": \"Resultado de conformidade que o agente deve garantir.\",\n",
        "            \"resumoMaterial\": \"Resumo da base tecnica que o agente usara como checklist.\",\n",
        "            \"atividades\": \"Acoes recorrentes que o agente deve executar ao revisar artefatos.\",\n",
        "            \"quandoAcionar\": \"Eventos, fases ou riscos que justificam acionar o agente.\",\n",
        "            \"entradasEsperadas\": \"Artefatos e evidencias que o operador deve fornecer ao agente.\",\n",
        "            \"saidasProduzidas\": \"Produtos esperados: parecer, checklist, riscos, correcoes e evidencias.\",\n",
        "            \"palavrasChave\": \"Termos usados para busca, roteamento e descoberta da spec/agente.\",\n",
        "            \"ferramentas\": \"Ferramentas autorizadas para o agente executar sua avaliacao.\"\n",
        "        },\n",
        "        \"materialTecnico\": {\n",
        "            \"resumo\": \"Sintese objetiva do que esta spec regula.\",\n",
        "            \"principiosSisc\": \"Principios de arquitetura SISC que nunca devem ser violados neste tema.\",\n",
        "            \"escopo\": \"O que deve ser coberto pela spec.\",\n",
        "            \"foraDeEscopo\": \"O que a spec nao deve decidir para evitar acoplamento indevido.\",\n",
        "            \"criteriosObrigatorios\": \"Regras obrigatorias e verificaveis; cada criterio deve poder ser aprovado/reprovado.\",\n",
        "            \"criteriosDeAprovacao\": \"Condicoes objetivas para considerar o artefato conforme.\",\n",
        "            \"evidenciasEsperadas\": \"Arquivos, testes, logs, contratos ou decisoes que provam conformidade.\",\n",
        "            \"riscosEAntipadroes\": \"Sinais de falha, atalhos proibidos e decisoes que exigem correcao.\",\n",
        "            \"perguntasParaContexto\": \"Perguntas que o agente/operador deve responder antes de aplicar a spec.\",\n",
        "            \"termosEssenciais\": \"Glossario minimo para evitar ambiguidade na revisao.\"\n",
        "        },\n",
        "        \"sincronizacao\": \"Metadados preenchidos automaticamente pelo comando; nao edite sem necessidade.\"\n",
        "    },\n",
        NULL
    };
    for (int i = 0; linhas[i]; i++) fputs(linhas[i], fp);
}

static void emitir_spec(FILE *fp, const char *perfil, const char *fontes, const char *arq, const char *cat, const char *tit)
{
    int modelo = !strcmp(cat, "modelo");
    char cat_kebab[512];
    kebab_id(cat, cat_kebab, sizeof(cat_kebab));
    const char *fonte_padrao = "\"TODO operador: informe fontes reais: arquivos do sistema, normas, documentacao, URLs e decisoes que fundamentam esta spec.\"";
    const char *fontes_emitir = fontes && fontes[0] ? fontes : fonte_padrao;

    fputs("{\n", fp);

    fputs("    \"tipo\": ", fp); jstr(fp, modelo ? "" : "diretiva-persona-agente"); fputs(",\n", fp);
    fputs("    \"perfilUso\": ", fp); jstr(fp, perfil); fputs(",\n", fp);
    fprintf(fp, "    \"fonteUnicaDeDescobertaAgente\": %s,\n", modelo ? "null" : "true");
    fprintf(fp, "    \"fonteInformacao\": [\n        %s\n    ],\n", fontes_emitir);
    fputs("    \"arquivo\": ", fp);
    if (modelo) {
        jstr(fp, "");
    } else {
        char caminho_arq[768];
        snprintf(caminho_arq, sizeof(caminho_arq), "spec-diretivas/%s", arq);
        jstr(fp, caminho_arq);
    }
    fputs(",\n", fp);
    fputs("    \"llm\": ", fp); jstr(fp, modelo ? "" : "atual.json"); fputs(",\n", fp);

    fputs("    \"aplicabilidadeSisc\": {\n", fp);
    fputs("        \"perfilPrimario\": [\n", fp);
    fprintf(fp, "            \"TODO operador: informe os perfis/cenarios em que a spec de %s se aplica\"\n", tit);
    fputs("        ],\n", fp);
    fprintf(fp, "        \"usarEscutaNativa\": %s,\n", modelo ? "null" : "true");
    fprintf(fp, "        \"naoImplementarProcessoDeMensagens\": %s,\n", modelo ? "null" : "true");
    fputs("        \"protocoloMensagem\": \"siscore-protocolo-objetos.v1\",\n", fp);
    fputs("        \"diretorioEspaco\": \"espaco/\",\n", fp);
    fprintf(fp, "        \"observacao\": \"TODO operador: explique como a spec de %s deve usar escuta.c, pp --api e o espaco nativo, sem mecanismo concorrente.\",\n", tit);
    fputs("        \"formatoEscutaCanonico\": \"formatos-escuta/protocolo-mensagem-siscore.v1.json\",\n", fp);
    fputs("        \"fonteDoFormatoDeMensagem\": \"formatos-escuta/protocolo-mensagem-siscore.v1.json\",\n", fp);
    fputs("        \"colocacaoNoEspaco\": \"Usar obrigatoriamente pp --api/API declarativa; nao escrever mensagens diretamente no espaco.\",\n", fp);
    fputs("        \"leituraDoEspaco\": \"Agentes e conectores devem processar apenas o arquivo de mensagem entregue pela escuta.\",\n", fp);
    fputs("        \"importacaoFormatoEscuta\": \"Novos sistemas devem copiar/importar o formato canonico do siscore quando necessario; nao criar formato concorrente.\",\n", fp);
    fputs("        \"apiDeclarativaCatalogo\": \"web-api/catalogo-mensagens.json\",\n", fp);
    fprintf(fp, "        \"proibirAcessoDiretoEntreAtores\": %s,\n", modelo ? "null" : "true");
    fputs("        \"comunicacaoEntreAtores\": \"somente via espaco SISC usando formatos-escuta e escuta.c\",\n", fp);
    fprintf(fp, "        \"publicacaoSomenteViaApi\": %s,\n", modelo ? "null" : "true");
    fputs("        \"validacaoPublicacaoEscuta\": \"A escuta deve validar origem/transporte e marcador de publicacao antes de aceitar mensagens no espaco.\"\n", fp);
    fputs("    },\n", fp);

    fputs("    \"agente\": {\n", fp);
    fprintf(fp, "        \"criar\": %s,\n", modelo ? "null" : "true");
    fputs("        \"nome\": ", fp); if (modelo) jstr(fp, ""); else { char b[768]; snprintf(b,sizeof(b),"agente-%s",cat_kebab); jstr(fp,b); } fputs(",\n", fp);
    fputs("        \"titulo\": ", fp); if (modelo) jstr(fp, ""); else { char b[1024]; snprintf(b,sizeof(b),"Agente de %s",tit); jstr(fp,b); } fputs(",\n", fp);
    fputs("        \"persona\": ", fp); if (modelo) jstr(fp, ""); else { char b[1024]; snprintf(b,sizeof(b),"Especialista senior responsavel por interpretar e aplicar a spec de %s com foco em conformidade tecnica e operacional.",tit); jstr(fp,b); } fputs(",\n", fp);
    fputs("        \"objetivo\": ", fp); if (modelo) jstr(fp, ""); else { char b[1024]; snprintf(b,sizeof(b),"Garantir que artefatos, decisoes e implementacoes estejam conformes com spec-diretivas/%s.",arq); jstr(fp,b); } fputs(",\n", fp);
    fputs("        \"resumoMaterial\": ", fp); if (modelo) jstr(fp, ""); else { char b[1024]; snprintf(b,sizeof(b),"Usar esta spec como checklist normativo para avaliar riscos, decisoes, codigo, contratos, testes e evidencias relacionados a %s.",tit); jstr(fp,b); } fputs(",\n", fp);
    fputs("        \"atividades\": [\n", fp);
    fputs("            \"Avaliar propostas de arquitetura, codigo, contratos, testes e operacao contra os criterios obrigatorios desta spec.\",\n", fp);
    fputs("            \"Identificar desvios, riscos, antipadroes e pendencias verificaveis.\",\n", fp);
    fprintf(fp, "            \"TODO operador: acrescente atividades especificas para %s.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"quandoAcionar\": [\n", fp);
    fputs("            \"Ao criar, revisar ou evoluir artefatos afetados por esta spec.\",\n", fp);
    fputs("            \"Antes de aprovar deploy, contrato, integracao externa ou decisao arquitetural relevante.\",\n", fp);
    fprintf(fp, "            \"TODO operador: informe gatilhos especificos para %s.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"entradasEsperadas\": [\n", fp);
    fputs("            \"Descricao do servico, modulo, fluxo ou decisao a ser avaliada.\",\n", fp);
    fputs("            \"Codigo, contratos, payloads, testes, logs, ADRs e evidencias operacionais relevantes.\",\n", fp);
    fputs("            \"TODO operador: liste entradas adicionais obrigatorias para esta spec.\"\n", fp);
    fputs("        ],\n", fp);
    fputs("        \"saidasProduzidas\": [\n", fp);
    fputs("            \"Checklist de conformidade com status aprovado, atencao ou reprovado.\",\n", fp);
    fputs("            \"Correcoes obrigatorias, riscos priorizados, recomendacoes implementaveis e evidencias esperadas.\",\n", fp);
    fputs("            \"TODO operador: descreva entregas especificas esperadas do agente.\"\n", fp);
    fputs("        ],\n", fp);
    fputs("        \"palavrasChave\": [\n", fp);
    fprintf(fp, "            \"%s\",\n", cat);
    fputs("            \"sisc\",\n", fp);
    fputs("            \"conformidade\",\n", fp);
    fputs("            \"TODO-operador-adicionar-termos-do-dominio\"\n", fp);
    fputs("        ],\n", fp);
    fputs("        \"ferramentas\": [\n", fp);
    fputs("            \"ler\",\n            \"escrever\",\n            \"deletar\",\n            \"procurar_arquivo\",\n            \"listar_arquivos\",\n            \"diferencas\",\n            \"internet\"\n", fp);
    fputs("        ]\n", fp);
    fputs("    },\n", fp);

    fputs("    \"materialTecnico\": {\n", fp);
    fputs("        \"resumo\": ", fp); if (modelo) jstr(fp, ""); else { char b[1024]; snprintf(b,sizeof(b),"Spec de %s. Define escopo, principios, criterios obrigatorios, aprovacao, evidencias, riscos e perguntas de contexto.",tit); jstr(fp,b); } fputs(",\n", fp);
    fputs("        \"principiosSisc\": [\n", fp);
    fputs("            \"A comunicacao entre atores SISC deve ocorrer exclusivamente pelo espaco nativo e pela escuta.c.\",\n", fp);
    fputs("            \"Nao implementar barramento, broker, fila, cron acoplado ou leitura direta para substituir o fluxo nativo do SISC.\",\n", fp);
    fprintf(fp, "            \"TODO operador: acrescente principios especificos para %s.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"escopo\": [\n", fp);
    fprintf(fp, "            \"TODO operador: liste quais artefatos, decisoes, modulos, fluxos e riscos de %s esta spec cobre.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"foraDeEscopo\": [\n", fp);
    fprintf(fp, "            \"TODO operador: liste o que nao deve ser decidido por esta spec de %s.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"criteriosObrigatorios\": [\n", fp);
    fputs("            \"A implementacao deve obedecer aos principios SISC declarados nesta spec.\",\n", fp);
    fprintf(fp, "            \"TODO operador: escreva criterios verificaveis, objetivos e reprovaveis para %s.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"criteriosDeAprovacao\": [\n", fp);
    fprintf(fp, "            \"TODO operador: defina condicoes objetivas que tornam uma entrega aprovada em %s.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"evidenciasEsperadas\": [\n", fp);
    fputs("            \"Testes automatizados, logs, contratos, ADRs, manifests ou capturas que comprovem conformidade.\",\n", fp);
    fprintf(fp, "            \"TODO operador: detalhe evidencias obrigatorias especificas para %s.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"riscosEAntipadroes\": [\n", fp);
    fputs("            \"Criar mecanismo paralelo que substitua escuta.c, pp --api ou o espaco nativo.\",\n", fp);
    fprintf(fp, "            \"TODO operador: liste riscos, atalhos proibidos e antipadroes especificos para %s.\"\n", tit);
    fputs("        ],\n", fp);
    fputs("        \"perguntasParaContexto\": [\n", fp);
    fprintf(fp, "            \"Quais artefatos de %s serao avaliados por esta spec?\",\n", tit);
    fputs("            \"Quais evidencias existem para provar conformidade?\",\n", fp);
    fputs("            \"TODO operador: acrescente perguntas que reduzam ambiguidade antes da avaliacao.\"\n", fp);
    fputs("        ],\n", fp);
    fputs("        \"termosEssenciais\": [\n", fp);
    fprintf(fp, "            \"%s\",\n", tit);
    fputs("            \"SISC\",\n", fp);
    fputs("            \"espaco\",\n", fp);
    fputs("            \"escuta.c\",\n", fp);
    fputs("            \"TODO operador: acrescente termos essenciais do dominio.\"\n", fp);
    fputs("        ]\n", fp);
    fputs("    },\n", fp);

    emitir_comentarios(fp);

    fputs("    \"sincronizacao\": {\n", fp);
    fputs("        \"formatadoPor\": \"pp --criar-spec\",\n", fp);
    fputs("        \"versao\": \"1.0.0\",\n", fp);
    fputs("        \"atualizadoPor\": \"pp --criar-spec\",\n", fp);
    fprintf(fp, "        \"atualizadoEm\": \"%ld\"\n", (long)time(NULL));
    fputs("    }\n", fp);
    fputs("}\n", fp);
}

int main(int argc,char**argv){
    if (restricao_verificar("criar-spec") != 0) return 1;
    if(argc<2||!strcmp(argv[1],"--help")||!strcmp(argv[1],"--ajuda")||!strcmp(argv[1],"-h")||!strncmp(argv[1],"--ajuda:",8)||!strncmp(argv[1],"--ajuda=",8)){uso();return argc==2?0:1;}

    char arq[512];
    if(nome_arquivo(argv[1],arq,sizeof(arq))!=0){fprintf(stderr,"criar-spec: nome invalido.\n");return 1;}

    char raiz[PATH_MAX];
    if(!getcwd(raiz,sizeof(raiz))){perror("criar-spec: getcwd");return 1;}

    char dir[PATH_MAX*2];
    snprintf(dir,sizeof(dir),"%s/spec-diretivas",raiz);
    if(garantir_dir(dir)!=0){fprintf(stderr,"criar-spec: nao foi possivel criar spec-diretivas.\n");return 1;}

    char path[PATH_MAX*2];
    if(juntar_path(path,sizeof(path),dir,arq)!=0){fprintf(stderr,"criar-spec: caminho da spec excede o limite.\n");return 1;}
    if(access(path,F_OK)==0){fprintf(stderr,"criar-spec: Spec ja existe: spec-diretivas/%s\n",arq);return 1;}
    {
        char raiz_sisc[PATH_MAX], path_bib[PATH_MAX*2];
        snprintf(raiz_sisc,sizeof(raiz_sisc),"%s",raiz);
        char *slash=strrchr(raiz_sisc,'/');
        if(slash&&slash!=raiz_sisc){
            *slash='\0';
            snprintf(path_bib,sizeof(path_bib),"%s/core/biblioteca-specs/%s",raiz_sisc,arq);
            if(access(path_bib,F_OK)==0){fprintf(stderr,"criar-spec: Spec ja existe na biblioteca: core/biblioteca-specs/%s\n",arq);return 1;}
        }
    }

    char cat[512],tit[512],fontes[4096],perfil[16];
    categoria(arq,cat,sizeof(cat));
    titulo(cat,tit,sizeof(tit));
    parse_opcoes(argc,argv,fontes,sizeof(fontes),perfil,sizeof(perfil));

    FILE*fp=fopen(path,"wb");
    if(!fp){perror("criar-spec");return 1;}
    emitir_spec(fp, perfil, fontes, arq, cat, tit);
    if(fclose(fp)!=0){perror("criar-spec: fclose");return 1;}

    printf("Spec criada: spec-diretivas/%s\n",arq);
    printf("Perfil de uso: %s\n",perfil);
    printf("Revise os TODO operador e comentariosOperador antes de finalizar.\n");
    printf("Revise/normalize depois com: pp --normalizar-spec=%s\n",arq);
    return 0;
}
