#!/bin/sh
#
# O bloco do passo 9 do corte so instala o crontab novo quando a conferencia
# bate?
#
#     sh scripts/ensaiar-crontab-do-passo-9.sh
#     sh scripts/ensaiar-crontab-do-passo-9.sh <copia do procedimento>
#     sh scripts/ensaiar-crontab-do-passo-9.sh <copia do procedimento> <copia da etapa 1>
#
# Sai com 0 quando os quatro casos abaixo dao o que devem; 1 quando algum nao
# da, e diz qual; 2 quando nao consegue medir (o bloco nao esta onde devia, ou
# falta `mktemp` ou `awk`). O argumento aponta o ensaio para uma COPIA do
# procedimento -- e como se falsifica sem tocar no arquivo de verdade.
#
# ---------------------------------------------------------------------------
# POR QUE ISTO EXISTE (06/10/2026, D331)
#
# O dono decidiu (lote de perguntas, pergunta 5) que o crontab volta no passo 9
# com o token no cabecalho, `curl -fsS -m` e `MAILTO` -- e, em 12/10/2026 (a
# resposta 128 (b)), sem e-mail: o aviso vai ao log do sistema, pelo `logger`
# (desde 07/11/2026, a fatia 113; abaixo). O bloco que faz a troca
# tinha uma conferencia que so IMPRIMIA as contagens, e o `crontab` vinha logo
# depois, sem nada entre os dois: quem colasse o bloco inteiro -- e e assim que
# se cola roteiro -- instalava o crontab com `Authorization: Bearer ` vazio nas
# 25 linhas quando o passo 7 nao tinha levado o `cron.token`, e com o `MAILTO`
# no molde. As 25 rotinas recebiam 401 e nenhum aviso saia. A primeira prova,
# num rascunho, mostrou que a conferencia ACUSAVA o erro, e nao que ela
# SEGURAVA a instalacao: o ensaio do token vazio terminava chamando o dublê do
# `crontab` depois de imprimir `0 Bearer`. Este ensaio pergunta o que importa:
# o arquivo foi instalado?
#
# ---------------------------------------------------------------------------
# COMO
#
# Tira do procedimento os dois blocos `bash` do passo 9 que vem antes de
# "**Confira depois de 10 minutos**" -- o que gera o crontab novo e o que confere
# e instala --, troca so os caminhos de producao (`/root/`, `/var/log/nginx/`)
# pelos de um diretorio temporario, e roda o MESMO texto com dubles de `php`
# (devolve o token do caso), `curl` (nao sai daqui) e `crontab` (copia o arquivo,
# em vez de instalar). Entre os dois blocos, o caso pode corrigir o arquivo "a
# mao" -- e o que o procedimento manda fazer quando a conferencia nao bate, antes
# de rodar so o segundo. O crontab de antes e inventado: 25 linhas nas formas
# que a tabela de `docs/f1-6-agendamento.md` mostra (`-m` antes e depois do `-s`,
# `> /dev/null` com e sem espaco, o `www` e o dominio raiz), uma delas a da
# apuracao dos royalties, um comentario e um `MAILTO=""`. Os tokens sao
# inventados, e o nome diz isso.
#
#   certo           o token preenchido: INSTALA, com o token novo nas 25 linhas,
#                   `token=`, o token velho e o `www` em nenhuma, o
#                   `|| logger -t rotinas "falhou (curl $?): <a rota>"` nas 25, o
#                   `MAILTO=""` na primeira e o aviso da apuracao dos royalties
#                   (o `case $R in *aviso*)`, o D364) na linha dela. E AS LINHAS
#                   RODAM, com um `curl` e um `logger` de mentira: a que da certo
#                   nao escreve no log, a que falha escreve o codigo e a rota, e
#                   a dos royalties escreve a resposta quando ela traz `aviso`
#   rotinas que     as quatro linhas das rotinas que sairam do codigo -- em 13/10/2026
#   sairam          o Dash. Colaboradores e o Fluxo de Movimento, em 25/10/2026 o
#                   relatorio de fidelizacao, em 04/11/2026 a Evasao das 04:10 -- e
#                   as das tres irmas que ficam (o Dash. Faturamento, das 05:35, a
#                   fidelizacao das 23:50 e o ticket medio das mesmas 04:10):
#                   INSTALA sem as quatro, com as irmas convertidas e as outras 25
#   o recuo da      a linha do `grep -vE` do recuo do passo 12 da etapa 1
#   etapa 1         (`docs/procedimento-de-corte-etapa-1.md`), sobre o mesmo
#                   crontab: tira as quatro e deixa as irmas e as outras 25
#   token vazio     o `cron.token` que o passo 7 nao levou: NAO instala
#   fora do molde   uma linha que a troca nao reconhece, cada uma pegando uma
#                   condicao diferente da conferencia: o `-sm` colado (sem
#                   `-fsS` e sem `-m`), o `--silent` por extenso (so sem
#                   `-fsS`), a linha sem `-m` (so sem o limite), o
#                   `2>/dev/null` no lugar do `2>&1` (o erro ainda descartado)
#                   e um `token=` fora da URL: NAO instala
#   a mao           corrigida entre os dois blocos (07/11/2026, a fatia 113):
#                   a linha sem o `logger`, o `logger` com outra marca, a linha
#                   no `www`, um `%` (o cron o troca por fim de linha), um
#                   `MAILTO` com endereco (a 128 (b) tirou o e-mail) e a linha
#                   dos royalties sem o `case` do aviso: NAO instala
#
# E O TESTE DO LOG DO SISTEMA DO 8 de "O que hoje bloqueia" (desde 07/11/2026; o
# do e-mail, de 08/10/2026, saiu com a 128 (b)): com o `logger`, escreve e conta;
# sem ele, diz que falta e conta zero; e a linha de um teste de antes nao conta
# -- rodado de novo com um `logger` que sai 0 sem escrever, conta zero (os casos
# estao no fim).
#
# O QUE ELE NAO AFIRMA: que o crontab de producao tem essas formas (ele nao
# esta no repositorio, porque tem o token), nem que o log do sistema de la guarda
# o que o `logger` escreve (e o 8, no servidor). A conferencia do bloco e o que
# pega a linha de forma desconhecida; este ensaio prova que ela segura a
# instalacao quando pega.

set -u

cd "$(dirname "$0")/.." || exit 2

PROCEDIMENTO="${1:-docs/procedimento-de-corte.md}"
[ -r "$PROCEDIMENTO" ] || { echo "NAO CONSEGUI MEDIR: nao li $PROCEDIMENTO" >&2; exit 2; }
ETAPA_1="${2:-docs/procedimento-de-corte-etapa-1.md}"
[ -r "$ETAPA_1" ] || { echo "NAO CONSEGUI MEDIR: nao li $ETAPA_1" >&2; exit 2; }
command -v awk > /dev/null 2>&1 || { echo "NAO CONSEGUI MEDIR: sem awk" >&2; exit 2; }

BASE=$(mktemp -d 2>/dev/null) || { echo "NAO CONSEGUI MEDIR: mktemp -d falhou" >&2; exit 2; }
trap 'rm -rf "$BASE"' EXIT INT TERM

# Os blocos do passo 9, ate a conta de depois dos 10 minutos: o primeiro em
# bloco1.sh, o segundo em bloco2.sh (desde 07/11/2026, para o caso corrigir o
# arquivo entre os dois, como o procedimento manda).
awk -v base="$BASE" '/^### 9\. / { dentro = 1; next }
     dentro && /^### / { exit }
     dentro && /\*\*Confira depois de 10 minutos\*\*/ { exit }
     dentro && /^```bash/ { codigo = 1; n++; next }
     dentro && codigo && /^```/ { codigo = 0; next }
     dentro && codigo { print > (base "/bloco" n ".sh") }' "$PROCEDIMENTO"

if [ ! -f "$BASE/bloco1.sh" ] || [ ! -f "$BASE/bloco2.sh" ] || [ -f "$BASE/bloco3.sh" ] \
    || ! grep -q 'crontab-antes-do-corte\.txt' "$BASE/bloco1.sh" \
    || ! grep -q '^[[:space:]]*crontab /root/crontab-depois-do-corte\.txt' "$BASE/bloco2.sh"; then
    echo "NAO CONSEGUI MEDIR: o passo 9 de $PROCEDIMENTO nao tem, antes de \"Confira depois de 10 minutos\", dois blocos -- o que gera /root/crontab-depois-do-corte.txt e o que o confere e instala" >&2
    exit 2
fi

# O crontab de antes, inventado.
montar_crontab() {
    {
        echo '# crontab INVENTADO para o ensaio do passo 9 -- o token tambem'
        echo 'MAILTO=""'
        i=1
        while [ "$i" -le 25 ]; do
            # A DA APURACAO DOS ROYALTIES (07/11/2026, o D364): a das 05:25, no `www`, no
            # lugar da 13 -- a conferencia exige uma, e so uma, com o aviso dela.
            if [ "$i" = 13 ]; then
                echo "25 5 * * * curl -m 600 -s \"https://www.franquiabv.com.br/api/cronjobs/relatoriosRoyaltiesAtualizar?token=TOKEN-VELHO-INVENTADO\" > /dev/null 2>&1"
                i=$((i + 1))
                continue
            fi
            case $((i % 4)) in
                0) echo "*/5 * * * * curl -m 180 -s \"https://franquiabv.com.br/api/cronjobs/rotina$i?token=TOKEN-VELHO-INVENTADO\" > /dev/null 2>&1" ;;
                1) echo "0 3 * * * curl -s -m 590 \"https://www.franquiabv.com.br/api/marketing/envios$i?token=TOKEN-VELHO-INVENTADO\" >/dev/null 2>&1" ;;
                2) echo "30 1 * * * curl -s -m 60 \"https://www.franquiabv.com.br/api/cupons/cuponsValidarVencimento?token=TOKEN-VELHO-INVENTADO&n=$i\" > /dev/null 2>&1" ;;
                3) echo "15 4 * * * curl -m 600 -s \"https://franquiabv.com.br/api/cronjobs/outra$i?token=TOKEN-VELHO-INVENTADO\" >/dev/null 2>&1" ;;
            esac
            i=$((i + 1))
        done
        # AS LINHAS A MAIS de um caso (13/10/2026): as rotinas que sairam do
        # codigo e as irmas que ficam, na forma do crontab de producao.
        if [ -n "${LINHAS_A_MAIS:-}" ]; then
            printf '%s\n' "$LINHAS_A_MAIS"
        fi
    } > "$1"
}

falhas=0
falhou() { echo "  - $1"; falhas=$((falhas + 1)); }

# caso <nome> <token> [<programa awk que muda a linha 5 do crontab de antes>] [<programa awk que corrige "a mao" o crontab novo, entre os dois blocos>]
caso() {
    nome="$1"; token="$2"; mudanca="${3:-}"; a_mao="${4:-}"
    dir="$BASE/$nome"
    mkdir -p "$dir/logs"
    : > "$dir/logs/access.log"
    montar_crontab "$dir/crontab-antes-do-corte.txt"
    if [ -n "$mudanca" ]; then
        awk "NR == 5 { $mudanca } { print }" "$dir/crontab-antes-do-corte.txt" > "$dir/t" \
            && mv "$dir/t" "$dir/crontab-antes-do-corte.txt"
        grep -q 'outra3' "$dir/crontab-antes-do-corte.txt" || { echo "NAO CONSEGUI MEDIR: a linha 5 do crontab inventado mudou de lugar" >&2; exit 2; }
    fi

    {
        echo "php() { printf %s '$token'; }"
        echo 'curl() { echo 401; }'
        echo "crontab() { cp \"\$1\" '$dir/instalado.txt'; }"
        sed -e "s|/root/|$dir/|g" -e "s|/var/log/nginx/|$dir/logs/|g" "$BASE/bloco1.sh"
        if [ -n "$a_mao" ]; then
            printf '%s\n' "$a_mao" > "$dir/a-mao.awk"
            echo "awk -f '$dir/a-mao.awk' '$dir/crontab-depois-do-corte.txt' > '$dir/t' && mv '$dir/t' '$dir/crontab-depois-do-corte.txt'"
        fi
        sed -e "s|/root/|$dir/|g" -e "s|/var/log/nginx/|$dir/logs/|g" "$BASE/bloco2.sh"
    } > "$dir/ensaio.sh"

    sh "$dir/ensaio.sh" > "$dir/saida.txt" 2>&1
}

# A LINHA DO CRONTAB RODADA, sem o horario, pelo `sh` -- como o cron a roda --, com um
# `curl` e um `logger` de mentira no caminho: o `curl` escreve `CURL_CORPO` e sai com
# `CURL_SAIDA`; o `logger` anota os argumentos em `LOGGER_SAIDA` (`$BASE/logger.txt`).
mkdir -p "$BASE/bin"
cat > "$BASE/bin/curl" <<'FIM'
#!/bin/sh
printf '%s' "$CURL_CORPO"
exit "${CURL_SAIDA:-0}"
FIM
cat > "$BASE/bin/logger" <<'FIM'
#!/bin/sh
printf '%s\n' "$*" >> "$LOGGER_SAIDA"
FIM
chmod +x "$BASE/bin/curl" "$BASE/bin/logger"

# rodar_linha <a linha do crontab> <o corpo> <a saida do curl>
rodar_linha() {
    : > "$BASE/logger.txt"
    comando=$(printf '%s\n' "$1" | sed -E 's/^([^ ]+ +){5}//')
    CURL_CORPO="$2" CURL_SAIDA="$3" LOGGER_SAIDA="$BASE/logger.txt" PATH="$BASE/bin:$PATH" sh -c "$comando" > /dev/null 2>&1
}

caso certo TOKEN-NOVO-INVENTADO
if [ ! -f "$BASE/certo/instalado.txt" ]; then
    falhou "certo: o bloco NAO instalou o crontab com o token preenchido (saida: $(tail -1 "$BASE/certo/saida.txt"))"
else
    f="$BASE/certo/instalado.txt"
    [ "$(grep -c 'Authorization: Bearer TOKEN-NOVO-INVENTADO"' "$f")" = 25 ] || falhou "certo: o token novo nao esta no cabecalho das 25 linhas"
    [ "$(grep -c 'token=' "$f")" = 0 ] || falhou "certo: sobrou token= na URL"
    [ "$(grep -c 'TOKEN-VELHO-INVENTADO' "$f")" = 0 ] || falhou "certo: sobrou o token velho"
    [ "$(grep -c -- ' -fsS ' "$f")" = 25 ] || falhou "certo: nem toda linha ficou com -fsS"
    [ "$(grep -c '2>&1' "$f")" = 0 ] || falhou "certo: sobrou 2>&1"
    [ "$(head -1 "$f")" = 'MAILTO=""' ] || falhou "certo: a primeira linha nao e o MAILTO vazio -- o cron mandaria a saida a algum lugar"
    [ "$(grep -c '^MAILTO=' "$f")" = 1 ] || falhou "certo: mais de um MAILTO"
    [ "$(grep -c 'www\.franquiabv' "$f")" = 0 ] || falhou "certo: sobrou o www -- a 194 (a) pos o dominio raiz"
    [ "$(grep -c '"https://franquiabv\.com\.br/api/' "$f")" = 25 ] || falhou "certo: nem toda linha ficou no dominio raiz"
    [ "$(grep -c ' || logger -t rotinas "falhou (curl \$?): /api/' "$f")" = 25 ] || falhou "certo: nem toda linha manda a falha ao log do sistema"
    [ "$(grep -c '/api/cronjobs/rotina4" -H "Authorization: Bearer TOKEN-NOVO-INVENTADO" > /dev/null || logger -t rotinas "falhou (curl \$?): /api/cronjobs/rotina4"$' "$f")" = 1 ] \
        || falhou "certo: a linha de uma rotina qualquer nao ficou na forma do procedimento"
    [ "$(grep -c ' R=$(curl -m 600 -fsS "https://franquiabv.com.br/api/cronjobs/relatoriosRoyaltiesAtualizar" -H "Authorization: Bearer TOKEN-NOVO-INVENTADO") || logger -t rotinas "falhou (curl \$?): /api/cronjobs/relatoriosRoyaltiesAtualizar"; case \$R in \*aviso\*) logger -t rotinas "/api/cronjobs/relatoriosRoyaltiesAtualizar: \$R" ;; esac$' "$f")" = 1 ] \
        || falhou "certo: a linha da apuracao dos royalties nao guarda a resposta nem manda o aviso ao log (o D364)"

    # AS LINHAS RODAM: a que da certo cala, a que falha avisa, e a dos royalties le o aviso.
    rotina=$(grep '/api/cronjobs/rotina4"' "$f")
    royalties=$(grep 'relatoriosRoyaltiesAtualizar' "$f")
    rodar_linha "$rotina" '{"sucesso":true}' 0
    [ ! -s "$BASE/logger.txt" ] || falhou "certo, rodada: a rotina que deu certo escreveu no log: $(cat "$BASE/logger.txt")"
    rodar_linha "$rotina" '' 22
    [ "$(cat "$BASE/logger.txt")" = '-t rotinas falhou (curl 22): /api/cronjobs/rotina4' ] \
        || falhou "certo, rodada: a rotina que deu 401 (o curl 22) nao escreveu a falha no log -- escreveu \"$(cat "$BASE/logger.txt")\""
    rodar_linha "$royalties" '{"sucesso":true,"aviso":"AVISO: o retrato de royalties de 06\/11\/2026 somou zero"}' 0
    [ "$(cat "$BASE/logger.txt")" = '-t rotinas /api/cronjobs/relatoriosRoyaltiesAtualizar: {"sucesso":true,"aviso":"AVISO: o retrato de royalties de 06\/11\/2026 somou zero"}' ] \
        || falhou "certo, rodada: o aviso da apuracao dos royalties nao foi ao log -- foi \"$(cat "$BASE/logger.txt")\""
    rodar_linha "$royalties" '{"sucesso":true}' 0
    [ ! -s "$BASE/logger.txt" ] || falhou "certo, rodada: a apuracao sem aviso escreveu no log: $(cat "$BASE/logger.txt")"
    rodar_linha "$royalties" '' 28
    [ "$(cat "$BASE/logger.txt")" = '-t rotinas falhou (curl 28): /api/cronjobs/relatoriosRoyaltiesAtualizar' ] \
        || falhou "certo, rodada: a apuracao que estourou o tempo (o curl 28) nao escreveu so a falha no log -- escreveu \"$(cat "$BASE/logger.txt")\""
fi

# AS QUATRO ROTINAS QUE SAIRAM DO CODIGO: em 13/10/2026 (a resposta 137 do dono) a do
# Dash. Colaboradores, as 23:30, e a do Fluxo de Movimento, as 07:00 do dia 1; em
# 25/10/2026 (a resposta 138 (a), a fatia 41) a do relatorio de fidelizacao, as 03:10;
# em 04/11/2026 (a mesma resposta, a fatia 76d, a CA3 da Carteira) a da Evasao, as 04:10.
# O crontab guardado da producao ainda as tem; o bloco as tira, e instala as outras.
# Sem o filtro, as quatro voltariam no corte com 404 todo dia.
#
# AS IRMAS QUE FICAM VAO JUNTO no crontab inventado (a revisao de 13/10/2026, e a
# fatia 41): a do Dash. Faturamento, das 05:35, comeca igual (`relatoriosDashboard`),
# e a `fidelizacaoAtualizar`, das 23:50, termina igual. Sem elas aqui, um filtro largo
# demais -- por `relatoriosDashboard` inteiro, ou por `[Ff]idelizacaoAtualizar` --
# passava verde e tirava uma rotina viva no corte. E A DO TICKET MEDIO (a fatia 76d):
# `unidadesTicketMedioAtualizar` roda nas MESMAS 04:10 da Evasao, e um filtro pelo
# horario (`^10 4 `), em vez do nome, a tiraria junto.
SAIRAM='relatoriosDashboard(Colaboradores|FluxoMovimento)Atualizar|relatoriosFidelizacaoAtualizar|relatoriosEvasaoAtualizar'
LINHAS_QUE_SAIRAM='30 23 * * * curl -m 600 -s "https://franquiabv.com.br/api/cronjobs/relatoriosDashboardColaboradoresAtualizar?token=TOKEN-VELHO-INVENTADO" > /dev/null 2>&1
0 7 1 * * curl -m 600 -s "https://www.franquiabv.com.br/api/cronjobs/relatoriosDashboardFluxoMovimentoAtualizar?token=TOKEN-VELHO-INVENTADO" >/dev/null 2>&1
10 3 * * * curl -m 600 -s "https://franquiabv.com.br/api/cronjobs/relatoriosFidelizacaoAtualizar?token=TOKEN-VELHO-INVENTADO" > /dev/null 2>&1
10 4 * * * curl -m 600 -s "https://franquiabv.com.br/api/cronjobs/relatoriosEvasaoAtualizar?token=TOKEN-VELHO-INVENTADO" > /dev/null 2>&1
35 5 * * * curl -m 600 -s "https://franquiabv.com.br/api/cronjobs/relatoriosDashboardFaturamentoAtualizar?token=TOKEN-VELHO-INVENTADO" > /dev/null 2>&1
50 23 * * * curl -m 600 -s "https://franquiabv.com.br/api/cronjobs/fidelizacaoAtualizar?token=TOKEN-VELHO-INVENTADO" > /dev/null 2>&1
10 4 * * * curl -m 600 -s "https://franquiabv.com.br/api/cronjobs/unidadesTicketMedioAtualizar?token=TOKEN-VELHO-INVENTADO" > /dev/null 2>&1'

# o crontab inventado tem as quatro que sairam e as tres irmas? (senao, nao mede nada)
conferir_inventado() {
    if [ "$(grep -c -E "$SAIRAM" "$1")" != 4 ] \
        || [ "$(grep -c 'relatoriosDashboardFaturamentoAtualizar' "$1")" != 1 ] \
        || [ "$(grep -c '/fidelizacaoAtualizar?' "$1")" != 1 ] \
        || [ "$(grep -c '^10 4 .*/unidadesTicketMedioAtualizar?' "$1")" != 1 ]; then
        echo "NAO CONSEGUI MEDIR: o crontab inventado de $1 nao tem as quatro linhas que sairam e as tres das irmas" >&2
        exit 2
    fi
}

LINHAS_A_MAIS="$LINHAS_QUE_SAIRAM"
caso rotinas-que-sairam TOKEN-NOVO-INVENTADO
LINHAS_A_MAIS=''
conferir_inventado "$BASE/rotinas-que-sairam/crontab-antes-do-corte.txt"
if [ ! -f "$BASE/rotinas-que-sairam/instalado.txt" ]; then
    falhou "rotinas que sairam: o bloco NAO instalou (saida: $(tail -1 "$BASE/rotinas-que-sairam/saida.txt"))"
else
    f="$BASE/rotinas-que-sairam/instalado.txt"
    [ "$(grep -c -E 'relatoriosDashboard(Colaboradores|FluxoMovimento)Atualizar' "$f")" = 0 ] || falhou "rotinas que sairam: o crontab instalado ainda chama a do Dash. Colaboradores ou a do Fluxo de Movimento -- dariam 404 todo dia"
    [ "$(grep -c 'relatoriosFidelizacaoAtualizar' "$f")" = 0 ] || falhou "rotinas que sairam: o crontab instalado ainda chama a do relatorio de fidelizacao (03:10) -- daria 404 todo dia"
    [ "$(grep -c 'relatoriosEvasaoAtualizar' "$f")" = 0 ] || falhou "rotinas que sairam: o crontab instalado ainda chama a da Evasao (04:10) -- daria 404 todo dia"
    [ "$(grep -c '/unidadesTicketMedioAtualizar" -H "Authorization: Bearer TOKEN-NOVO-INVENTADO"' "$f")" = 1 ] || falhou "rotinas que sairam: a do ticket medio, das mesmas 04:10 da Evasao, saiu do crontab ou nao foi convertida -- o filtro pegou a irma"
    [ "$(grep -c 'relatoriosDashboardFaturamentoAtualizar" -H "Authorization: Bearer TOKEN-NOVO-INVENTADO"' "$f")" = 1 ] || falhou "rotinas que sairam: a do Dash. Faturamento, que continua no codigo, saiu do crontab ou nao foi convertida -- o filtro pegou a irma"
    [ "$(grep -c '/fidelizacaoAtualizar" -H "Authorization: Bearer TOKEN-NOVO-INVENTADO"' "$f")" = 1 ] || falhou "rotinas que sairam: a fidelizacao das 23:50, que continua no codigo, saiu do crontab ou nao foi convertida -- o filtro pegou a irma"
    [ "$(grep -c 'Authorization: Bearer TOKEN-NOVO-INVENTADO"' "$f")" = 28 ] || falhou "rotinas que sairam: as outras 25 e as tres irmas nao ficaram"
fi

# O RECUO DA ETAPA 1 (25/10/2026, a fatia 41): o passo 12 de `procedimento-de-corte-etapa-1.md`
# tem um filtro proprio, um `grep -vE` sobre o crontab de antes, e ele tem de tirar as mesmas
# quatro (a da Evasao desde 04/11/2026, a fatia 76d). Daqui se tira so essa linha -- a conferencia do token do recuo nao e ensaiada --, e ela
# roda sobre o mesmo crontab inventado, com os caminhos de producao trocados.
awk '/^### 12\. / { dentro = 1; next }
     dentro && /^### / { exit }
     dentro && /^grep -vE .*\/root\/crontab-antes-do-corte\.txt > \/root\/crontab-recuo\.txt$/ { print }' "$ETAPA_1" > "$BASE/recuo.sh"
if [ "$(grep -c . "$BASE/recuo.sh")" != 1 ]; then
    echo "NAO CONSEGUI MEDIR: o passo 12 de $ETAPA_1 nao tem uma, e so uma, linha 'grep -vE ... /root/crontab-antes-do-corte.txt > /root/crontab-recuo.txt'" >&2
    exit 2
fi
mkdir -p "$BASE/recuo"
LINHAS_A_MAIS="$LINHAS_QUE_SAIRAM"
montar_crontab "$BASE/recuo/crontab-antes-do-corte.txt"
LINHAS_A_MAIS=''
conferir_inventado "$BASE/recuo/crontab-antes-do-corte.txt"
sed -e "s|/root/|$BASE/recuo/|g" "$BASE/recuo.sh" > "$BASE/recuo/ensaio.sh"
sh "$BASE/recuo/ensaio.sh" > "$BASE/recuo/saida.txt" 2>&1
f="$BASE/recuo/crontab-recuo.txt"
if [ ! -f "$f" ]; then
    falhou "o recuo da etapa 1: o grep -vE nao gravou o crontab do recuo ($(tail -1 "$BASE/recuo/saida.txt"))"
else
    [ "$(grep -c -E "$SAIRAM" "$f")" = 0 ] || falhou "o recuo da etapa 1: o crontab do recuo ainda chama uma das quatro rotinas que sairam do codigo -- daria 404 todo dia"
    [ "$(grep -c 'relatoriosDashboardFaturamentoAtualizar' "$f")" = 1 ] || falhou "o recuo da etapa 1: o filtro tirou a do Dash. Faturamento, que continua no codigo"
    [ "$(grep -c '/fidelizacaoAtualizar?' "$f")" = 1 ] || falhou "o recuo da etapa 1: o filtro tirou a fidelizacao das 23:50, que continua no codigo"
    [ "$(grep -c '/unidadesTicketMedioAtualizar?' "$f")" = 1 ] || falhou "o recuo da etapa 1: o filtro tirou o ticket medio das 04:10, que continua no codigo"
    [ "$(grep -c 'curl ' "$f")" = 28 ] || falhou "o recuo da etapa 1: as outras 25 e as tres irmas nao ficaram ($(grep -c 'curl ' "$f") linhas de curl)"
fi

caso token-vazio ''
[ -f "$BASE/token-vazio/instalado.txt" ] && falhou "token vazio: o bloco INSTALOU o crontab com 'Authorization: Bearer ' vazio -- as rotinas parariam com 401"

caso s-colado TOKEN-NOVO-INVENTADO 'sub(/ -m 600 -s /, " -sm 600 ")'
[ -f "$BASE/s-colado/instalado.txt" ] && falhou "linha com -sm colado: o bloco INSTALOU o crontab com uma linha sem -fsS e sem -m"

caso silent-por-extenso TOKEN-NOVO-INVENTADO 'sub(/ -m 600 -s /, " -m 600 --silent ")'
[ -f "$BASE/silent-por-extenso/instalado.txt" ] && falhou "linha com --silent: o bloco INSTALOU o crontab com uma linha sem -fsS"

caso sem-limite TOKEN-NOVO-INVENTADO 'sub(/ -m 600 -s /, " -s ")'
[ -f "$BASE/sem-limite/instalado.txt" ] && falhou "linha sem -m: o bloco INSTALOU o crontab com uma rotina sem tempo limite"

caso erro-descartado TOKEN-NOVO-INVENTADO 'sub(/ 2>&1/, " 2>/dev/null")'
[ -f "$BASE/erro-descartado/instalado.txt" ] && falhou "linha com 2>/dev/null: o bloco INSTALOU o crontab com o erro de uma linha descartado"

caso token-fora-da-url TOKEN-NOVO-INVENTADO 'sub(/ >\/dev\/null/, " -d \"token=TOKEN-VELHO-INVENTADO\" >/dev/null")'
[ -f "$BASE/token-fora-da-url/instalado.txt" ] && falhou "linha com token= fora da URL: o bloco INSTALOU o crontab com o token velho escrito"

# CORRIGIDAS A MAO ENTRE OS DOIS BLOCOS (07/11/2026, a fatia 113; o D331, a resposta 128
# (b)): o procedimento manda corrigir a linha fora do molde em crontab-depois-do-corte.txt
# e rodar so o segundo bloco. Cada uma pega uma condicao nova da conferencia.
caso a-mao-sem-logger TOKEN-NOVO-INVENTADO '' '/\/rotina4"/ { sub(/ \|\| logger.*$/, "") } { print }'
[ -f "$BASE/a-mao-sem-logger/instalado.txt" ] && falhou "a mao, a linha sem o logger: o bloco INSTALOU o crontab com uma rotina que falharia calada"

caso a-mao-outra-marca TOKEN-NOVO-INVENTADO '' '/\/rotina4"/ { sub(/logger -t rotinas/, "logger -t cron") } { print }'
[ -f "$BASE/a-mao-outra-marca/instalado.txt" ] && falhou "a mao, o logger com outra marca: o bloco INSTALOU o crontab com um aviso que o journalctl -t rotinas nao acha"

caso a-mao-www TOKEN-NOVO-INVENTADO '' '/\/rotina4"/ { sub(/https:\/\/franquiabv/, "https://www.franquiabv") } { print }'
[ -f "$BASE/a-mao-www/instalado.txt" ] && falhou "a mao, a linha no www: o bloco INSTALOU o crontab fora do dominio raiz"

caso a-mao-percentual TOKEN-NOVO-INVENTADO '' '/\/rotina4"/ { sub(/\/rotina4" -H/, "/rotina4?de=10%25\" -H") } { print }'
[ -f "$BASE/a-mao-percentual/instalado.txt" ] && falhou "a mao, um % na linha: o bloco INSTALOU o crontab com uma linha que o cron cortaria"

caso a-mao-mailto TOKEN-NOVO-INVENTADO '' 'NR == 1 { $0 = "MAILTO=rotinas@exemplo.test" } { print }'
[ -f "$BASE/a-mao-mailto/instalado.txt" ] && falhou "a mao, o MAILTO com endereco: o bloco INSTALOU o crontab com o e-mail que a 128 (b) tirou"

caso a-mao-royalties-sem-aviso TOKEN-NOVO-INVENTADO '' '/relatoriosRoyaltiesAtualizar/ { sub(/; case .*$/, "") } { print }'
[ -f "$BASE/a-mao-royalties-sem-aviso/instalado.txt" ] && falhou "a mao, a apuracao dos royalties sem o case: o bloco INSTALOU o crontab sem o aviso do D364"

caso a-mao-royalties-duas-vezes TOKEN-NOVO-INVENTADO '' '{ print } /relatoriosRoyaltiesAtualizar/ { print }'
[ -f "$BASE/a-mao-royalties-duas-vezes/instalado.txt" ] && falhou "a mao, a apuracao dos royalties duas vezes: o bloco INSTALOU o crontab com duas apuracoes no mesmo minuto"

# ---------------------------------------------------------------------------
# O TESTE DO LOG DO SISTEMA, o 8 de "O que hoje bloqueia" (07/11/2026, a fatia
# 113; a resposta 128 (b) do dono, o D331). Ate aqui era o teste do e-mail do cron
# (08/10/2026, a resposta 31), e a 128 (b) tirou o e-mail: o aviso de cada linha
# do crontab vai ao log do sistema pelo `logger`, e o 8 confere que ele existe e
# que o log guarda o que ele escreve. Aqui o bloco roda com um `logger` de
# mentira (escreve no log do sistema inventado e no journal), um `journalctl` de
# mentira (le o journal inventado) e a linha de um teste de antes no girado `.gz`
# e no journal: com o `logger`, a contagem e 2 (o log de agora e o journal; a de
# antes nao conta, porque o bloco marca a linha com a hora e o numero do
# processo); sem ele, `SEM O logger` e zero; e rodado de novo, depois de um
# primeiro que chegou, com um `logger` que sai 0 sem escrever, zero.
command -v gzip > /dev/null 2>&1 || { echo "NAO CONSEGUI MEDIR: sem gzip" >&2; exit 2; }
awk '/^### O que hoje bloqueia/ { dentro = 1; next }
     dentro && /^### / { exit }
     dentro && /^\*\*O 8, o teste do aviso no log do sistema\*\*/ { achou = 1; next }
     achou && /^```bash/ { codigo = 1; next }
     achou && codigo && /^```/ { exit }
     achou && codigo { print }' "$PROCEDIMENTO" > "$BASE/bloco-do-8.sh"
if ! grep -q '^/usr/bin/logger -t rotinas ' "$BASE/bloco-do-8.sh" || ! grep -q '/var/log/syslog' "$BASE/bloco-do-8.sh" \
    || ! grep -q 'journalctl -t rotinas' "$BASE/bloco-do-8.sh"; then
    echo "NAO CONSEGUI MEDIR: o 8 de \"O que hoje bloqueia\" de $PROCEDIMENTO nao tem, no bloco logo depois de \"**O 8, o teste do aviso no log do sistema**\", o /usr/bin/logger -t rotinas, a leitura de /var/log/syslog e o journalctl -t rotinas" >&2
    exit 2
fi

# preparar_o_8 <nome>: o log do sistema inventado, com a linha de um teste de
# antes no girado `.gz` e no journal (a mesma frase, com a marca de outro dia), e
# os tres `logger` de mentira: o que escreve no log e no journal, o que sai 0 sem
# escrever nada (o caminho do log quebrado depois do teste de antes) e o que nao
# existe.
preparar_o_8() {
    dir="$BASE/oito-$1"
    mkdir -p "$dir/log"
    printf 'Nov  7 10:06:00 servidor outra coisa\n' > "$dir/log/syslog"
    printf 'Nov  5 10:00:01 servidor rotinas: teste do aviso das rotinas (franquiabv, 1762336801-4242)\n' | gzip -c > "$dir/log/syslog.2.gz"
    printf 'Nov 05 servidor rotinas[5]: teste do aviso das rotinas (franquiabv, 1762336801-4242)\n' > "$dir/journal"
    printf '#!/bin/sh\nprintf "Nov  7 10:07:00 servidor %%s: %%s\\n" "$2" "$3" >> "%s/log/syslog"\nprintf "Nov 07 servidor %%s[9]: %%s\\n" "$2" "$3" >> "%s/journal"\n' "$dir" "$dir" > "$dir/logger"
    printf '#!/bin/sh\nexit 0\n' > "$dir/logger-mudo"
    chmod +x "$dir/logger" "$dir/logger-mudo"
}

# rodar_o_8 <nome> <qual logger: logger, logger-mudo ou logger-que-nao-existe> <saida>
rodar_o_8() {
    dir="$BASE/oito-$1"
    {
        printf '%s\n' "journalctl() { cat '$dir/journal'; }"
        printf '%s\n' "sleep() { :; }"
        sed -e "s|/usr/bin/logger|$dir/$2|g" -e "s|/var/log/syslog|$dir/log/syslog|g" "$BASE/bloco-do-8.sh"
    } > "$dir/ensaio-$3.sh"
    sh "$dir/ensaio-$3.sh" > "$dir/$3" 2>&1
}

# contagem_do_8 <arquivo>: a linha so de digitos que o `grep -c` imprimiu
contagem_do_8() {
    grep -E '^[[:space:]]*[0-9]+[[:space:]]*$' "$1" | tr -d ' '
}

# O GIRADO: a linha do teste de agora nunca esta num `.gz`, e por isso nenhum caso
# abaixo pega o `grep` no lugar do `zgrep`; e o `zgrep` que a tabela do 8 manda
# usar depois do corte, para ler os girados. Lido sem os comentarios.
grep -v '^[[:space:]]*#' "$BASE/bloco-do-8.sh" | grep -q 'zgrep -h .* /var/log/syslog\*' \
    || falhou "o 8: o bloco nao le o log do sistema com zgrep (o grep leria o girado .gz como binario)"

preparar_o_8 com-logger
rodar_o_8 com-logger logger saida.txt
grep -q 'ESCRITO' "$BASE/oito-com-logger/saida.txt" || falhou "o 8, com o logger: a saida nao diz ESCRITO"
grep -q 'servidor rotinas: teste do aviso das rotinas' "$BASE/oito-com-logger/log/syslog" || falhou "o 8, com o logger: a linha nao foi escrita com a marca rotinas"
[ "$(contagem_do_8 "$BASE/oito-com-logger/saida.txt")" = 2 ] \
    || falhou "o 8: a contagem nao deu 2 (a linha de agora no log e no journal, e nenhuma do teste de antes) -- deu \"$(contagem_do_8 "$BASE/oito-com-logger/saida.txt")\""

preparar_o_8 sem-logger
rodar_o_8 sem-logger logger-que-nao-existe saida.txt
grep -q 'SEM O logger' "$BASE/oito-sem-logger/saida.txt" || falhou "o 8, sem o logger: a saida nao diz SEM O logger"
grep -q 'ESCRITO' "$BASE/oito-sem-logger/saida.txt" && falhou "o 8, sem o logger: a saida diz ESCRITO"
[ "$(contagem_do_8 "$BASE/oito-sem-logger/saida.txt")" = 0 ] \
    || falhou "o 8, sem o logger: a contagem nao deu zero (contou a linha do teste de antes) -- deu \"$(contagem_do_8 "$BASE/oito-sem-logger/saida.txt")\""

# O 8 DE NOVO, ANTES DA ETAPA 2 (a verificacao da 113, 07/11/2026): o teste de
# antes da etapa 1 chegou, e depois o caminho do log quebrou -- o `logger` sai 0
# e nada chega. A linha de antes segue no log de agora e no journal; a contagem
# tem de ser zero, ou a tabela diria "o log do sistema guarda o aviso".
preparar_o_8 de-novo
rodar_o_8 de-novo logger antes.txt
[ "$(contagem_do_8 "$BASE/oito-de-novo/antes.txt")" = 2 ] || falhou "o 8 de novo: o primeiro teste nao contou 2"
rodar_o_8 de-novo logger-mudo depois.txt
grep -q 'ESCRITO' "$BASE/oito-de-novo/depois.txt" || falhou "o 8 de novo: o logger mudo sai 0, e a saida nao diz ESCRITO"
[ "$(contagem_do_8 "$BASE/oito-de-novo/depois.txt")" = 0 ] \
    || falhou "o 8 de novo, com o caminho do log quebrado: a contagem nao deu zero (contou a linha do teste de antes, o verde falso) -- deu \"$(contagem_do_8 "$BASE/oito-de-novo/depois.txt")\""

if [ "$falhas" -gt 0 ]; then
    echo "O BLOCO DO PASSO 9 NAO SEGURA O CRONTAB ERRADO ($PROCEDIMENTO): $falhas caso(s)"
    exit 1
fi

echo "ok: o bloco do passo 9 instala o crontab certo -- sem as quatro rotinas que sairam (e o filtro do recuo da etapa 1 tambem as tira), com o aviso no log em cada linha e o da apuracao dos royalties, que rodam como devem -- e recusa o token vazio, a linha fora do molde e a corrigida a mao sem o aviso; e o teste do 8 escreve no log do sistema e conta so a linha de agora, no log e no journal, e nunca a de um teste de antes"
exit 0
