#!/bin/sh
# ---------------------------------------------------------------------------
# A conta de quem chama as tres unidadeVendas* conta o que diz, e so isso?
#
#     sh scripts/ensaiar-medir-chamadas-unidade-vendas.sh
#
# Sai com 0 quando tudo bate; 1 quando algo nao bate, e diz o que; 2 quando nao
# consegue medir (sem awk, sem gzip, sem diretorio temporario).
#
# POR QUE ISTO EXISTE (08/10/2026). `scripts/medir-chamadas-unidade-vendas.sh`
# roda uma vez, na producao, no dia 0 (o 9 de "O que hoje bloqueia", no
# `docs/procedimento-de-corte.md`), e o numero dele volta ao dono como resposta
# da pergunta 6 do lote. Errado ali, ninguem refaz. Este ensaio roda a conta
# sobre um log de acesso INVENTADO, no formato `combined`, com IPs dos blocos de
# documentacao (192.0.2.0/24) e um `hash` que diz que e inventado -- nenhum log
# de ninguem.
#
# O QUE ELE AFIRMA, sobre dois arquivos (um em texto, um em `.gz`) e a entrada
# padrao:
#   1. as tres rotas contam por dia, de qualquer metodo, com a query cortada --
#      e tambem com o `/index.php/` na frente e com a URL inteira no pedido,
#      as duas formas que chegam a exportacao (200 no nginx daqui);
#   2. NAO contam: a rota dentro do referer, do user-agent ou da query de outra
#      rota; a `vendedores`; a linha do log de erro; o pedido "-" -- e o que e
#      parecido (a barra no fim, a barra dobrada, outra caixa, a `vendasV4`)
#      vai a "parecidos";
#   3. o controle `/api/versao/app` conta por dia, nas tres formas, e o dia sem
#      ele sai marcado;
#   4. a saida nao tem IP, `hash`, host, user-agent nem valor de query;
#   5. sai com 2 com o controle em zero, sem linha no formato, e com um arquivo
#      que nao se le -- e com 0 no caso certo;
#   6. o procedimento de corte ainda manda roda-la, e o COMANDO dele funciona:
#      a linha do `ssh` (num bloco `bash`, fora de comentario) roda aqui, com
#      o diretorio dos logs trocado por um inventado, e da o mesmo que a conta
#      chamada direto. A frase da tabela, sozinha, nao basta (a revisao de
#      08/10/2026: a primeira versao procurava o nome do roteiro na secao
#      inteira, e a celula da tabela a satisfazia sem comando nenhum).
# ---------------------------------------------------------------------------

set -u

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

CONTA=scripts/medir-chamadas-unidade-vendas.sh
PROCEDIMENTO="${1:-docs/procedimento-de-corte.md}"
[ -r "$CONTA" ] || { echo "NAO CONSEGUI MEDIR: nao li $CONTA" >&2; exit 2; }
[ -r "$PROCEDIMENTO" ] || { echo "NAO CONSEGUI MEDIR: nao li $PROCEDIMENTO" >&2; exit 2; }
for p in awk gzip; do
    command -v "$p" > /dev/null 2>&1 || { echo "NAO CONSEGUI MEDIR: sem $p" >&2; exit 2; }
done

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

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

H='HASH-INVENTADO-NAO-IMPRIMA'
UA='AgenteInventado/1.0'

# O arquivo de texto: os dias 05, 06 e 07. O 05 nao tem o controle.
cat > "$BASE/site.access.log" <<FIM
192.0.2.10 - - [05/Oct/2026:23:59:01 -0300] "GET /api/unidade/vendas?id=7&hash=$H&inicio=2026-09-01&fim=2026-09-30 HTTP/1.1" 200 14 "-" "$UA"
192.0.2.10 - - [06/Oct/2026:10:00:01 -0300] "GET /api/versao/app?versao=2.0.8 HTTP/1.1" 200 77 "-" "$UA"
192.0.2.11 - - [06/Oct/2026:10:00:02 -0300] "GET /api/versao/app HTTP/1.1" 200 77 "-" "$UA"
192.0.2.12 - - [06/Oct/2026:10:05:00 -0300] "GET /api/unidade/vendas?id=7&hash=$H&inicio=2026-09-01 HTTP/1.1" 200 4096 "-" "$UA"
192.0.2.12 - - [06/Oct/2026:10:06:00 -0300] "GET /api/unidade/vendas?id=8&hash=$H HTTP/1.1" 200 14 "-" "$UA"
192.0.2.13 - - [06/Oct/2026:10:07:00 -0300] "GET /api/unidade/vendasV4?hash=$H HTTP/1.1" 404 0 "-" "$UA"
192.0.2.14 - - [06/Oct/2026:10:08:00 -0300] "GET /index.html HTTP/1.1" 200 900 "https://exemplo.test/api/unidade/vendas?hash=$H" "$UA"
2026/10/06 10:09:00 [error] 12#12: *1 open() "/var/www/html/public/api/unidade/vendas" failed (2: No such file or directory), client: 192.0.2.99
192.0.2.10 - - [07/Oct/2026:09:00:00 -0300] "GET /api/versao/app HTTP/1.1" 200 77 "-" "$UA"
192.0.2.15 - - [07/Oct/2026:09:01:00 -0300] "GET /api/unidade/vendasV2?id=7&hash=$H HTTP/1.1" 200 2048 "-" "$UA"
192.0.2.15 - - [07/Oct/2026:09:02:00 -0300] "GET /api/unidade/vendas/?id=7&hash=$H HTTP/1.1" 404 0 "-" "$UA"
192.0.2.16 - - [07/Oct/2026:09:03:00 -0300] "GET /api/cronjobs/npsContabilizar?volta=/api/unidade/vendas HTTP/1.1" 401 60 "-" "curl/8.0"
192.0.2.17 - - [07/Oct/2026:09:04:00 -0300] "-" 400 0 "-" "-"
192.0.2.18 - - [07/Oct/2026:09:05:00 -0300] "GET /index.php/api/unidade/vendas?id=7&hash=$H HTTP/1.1" 200 14 "-" "$UA"
192.0.2.18 - - [07/Oct/2026:09:06:00 -0300] "GET http://franquiabv.exemplo.test/api/unidade/vendasV3?id=7&hash=$H HTTP/1.1" 200 14 "-" "$UA"
192.0.2.18 - - [07/Oct/2026:09:07:00 -0300] "GET https://franquiabv.exemplo.test:8443/index.php/api/versao/app HTTP/1.1" 200 77 "-" "$UA"
192.0.2.18 - - [07/Oct/2026:09:08:00 -0300] "GET //api/unidade/vendas?hash=$H HTTP/1.1" 404 0 "-" "$UA"
192.0.2.18 - - [07/Oct/2026:09:09:00 -0300] "GET /index.php/api/unidade/vendas/?hash=$H HTTP/1.1" 404 0 "-" "$UA"
FIM

# O .gz: o dia 08.
cat > "$BASE/www.site.access.log.2" <<FIM
192.0.2.20 - - [08/Oct/2026:08:00:00 -0300] "GET /api/versao/app HTTP/1.1" 200 77 "-" "$UA"
192.0.2.20 - - [08/Oct/2026:08:00:01 -0300] "GET /api/versao/app HTTP/1.1" 200 77 "-" "$UA"
192.0.2.21 - - [08/Oct/2026:08:00:02 -0300] "GET /api/versao/app?versao=1.9.0 HTTP/1.1" 200 77 "-" "$UA"
192.0.2.22 - - [08/Oct/2026:08:10:00 -0300] "GET /api/unidade/vendasV3?id=7&hash=$H&inicio=2026-10-01&fim=2026-10-07 HTTP/2.0" 200 8192 "-" "$UA"
192.0.2.22 - - [08/Oct/2026:08:11:00 -0300] "GET /API/Unidade/Vendas?hash=$H HTTP/1.1" 404 0 "-" "$UA"
192.0.2.23 - - [08/Oct/2026:08:12:00 -0300] "GET /qualquer HTTP/1.1" 200 10 "-" "Robo /api/unidade/vendas"
192.0.2.23 - - [08/Oct/2026:08:13:00 -0300] "GET /api/unidade/vendedores?hash=$H HTTP/1.1" 404 0 "-" "$UA"
192.0.2.24 - - [08/Oct/2026:08:14:00 -0300] "POST /api/unidade/vendas HTTP/1.1" 200 14 "-" "$UA"
FIM
gzip -9 "$BASE/www.site.access.log.2" || { echo "NAO CONSEGUI MEDIR: gzip falhou" >&2; exit 2; }

# A linha de um dia na saida, por campos: dia, do site, controle, vendas, V2, V3, parecidos.
linha_do_dia() { awk -v d="$2" '$1 == d { print $1, $2, $3, $4, $5, $6, $7 }' "$1"; }

# --- 1 a 4: os dois arquivos ------------------------------------------------
sh "$CONTA" "$BASE/site.access.log" "$BASE/www.site.access.log.2.gz" > "$BASE/saida.txt" 2> "$BASE/erro.txt"
codigo=$?
[ "$codigo" = 0 ] || falhou "os dois arquivos: saiu com $codigo, e o esperado era 0 ($(tail -1 "$BASE/saida.txt"))"

for esperado in \
    '2026-10-05 1 0 1 0 0 0' \
    '2026-10-06 6 2 2 0 0 1' \
    '2026-10-07 9 2 1 1 1 3' \
    '2026-10-08 8 3 1 0 1 1'; do
    dia=${esperado%% *}
    lido=$(linha_do_dia "$BASE/saida.txt" "$dia")
    [ "$lido" = "$esperado" ] || falhou "o dia $dia deu \"$lido\"; o esperado era \"$esperado\" (do site, controle, vendas, vendasV2, vendasV3, parecidos -- no dia 07, o /index.php/ e a URL inteira contam como as tres e como o controle)"
done
total=$(awk '$1 == "total" { print $2, $3, $4, $5, $6 }' "$BASE/saida.txt")
[ "$total" = '7 5 1 2 5' ] || falhou "o total deu \"$total\"; o esperado era \"7 5 1 2 5\" (controle, vendas, vendasV2, vendasV3, parecidos)"
grep -q '^AS TRES: 8 pedido(s) -- vendas 5, vendasV2 1, vendasV3 2 -- e 5 parecido(s)\.$' "$BASE/saida.txt" \
    || falhou "a linha AS TRES nao diz 8 pedidos (5, 1, 2) e 5 parecidos"
grep -q '^JANELA: 4 dia(s) com linha, de 2026-10-05 a 2026-10-08\.$' "$BASE/saida.txt" \
    || falhou "a JANELA nao diz 4 dias, de 2026-10-05 a 2026-10-08"
grep '^  2026-10-05 ' "$BASE/saida.txt" | grep -q 'o controle deu zero' \
    || falhou "o dia 05, sem o controle, nao saiu marcado"
if grep '^  2026-10-0[678] ' "$BASE/saida.txt" | grep -q 'o controle deu zero'; then
    falhou "um dia com o controle saiu marcado como sem ele"
fi
por_arquivo=$(awk '$NF ~ /site\.access\.log$/ { print $1, $2, $3 } $NF ~ /\.gz$/ { print $1, $2, $3 }' "$BASE/saida.txt" | tr '\n' '|')
[ "$por_arquivo" = '18 16 10|8 8 3|' ] || falhou "por arquivo deu \"$por_arquivo\"; o esperado era \"18 16 10|8 8 3|\" (linhas, no formato, das tres)"

for segredo in "$H" "$UA" '192.0.2.' 'inicio=' 'volta=' 'Robo' 'curl/8.0' 'exemplo.test' '8443'; do
    if grep -qF -- "$segredo" "$BASE/saida.txt" "$BASE/erro.txt"; then
        falhou "a saida imprime \"$segredo\": a conta so pode dizer o dia e o caminho"
    fi
done

# --- a entrada padrao -------------------------------------------------------
sh "$CONTA" < "$BASE/site.access.log" > "$BASE/stdin.txt" 2>&1
codigo=$?
[ "$codigo" = 0 ] || falhou "pela entrada padrao: saiu com $codigo, e o esperado era 0"
total=$(awk '$1 == "total" { print $2, $3, $4, $5, $6 }' "$BASE/stdin.txt")
[ "$total" = '4 4 1 1 4' ] || falhou "pela entrada padrao, o total deu \"$total\"; o esperado era \"4 4 1 1 4\""
grep -q '(entrada padrao)' "$BASE/stdin.txt" || falhou "pela entrada padrao, o arquivo nao saiu como (entrada padrao)"

# --- 5: o que nao mede ------------------------------------------------------
grep '/api/unidade/vendas' "$BASE/site.access.log" | grep -v 'versao' > "$BASE/sem-controle.log"
sh "$CONTA" "$BASE/sem-controle.log" > "$BASE/sem-controle.txt" 2>&1
codigo=$?
[ "$codigo" = 2 ] || falhou "sem o controle: saiu com $codigo, e o esperado era 2 (o zero das tres nao quer dizer nada)"
grep -q 'o controle (/api/versao/app) deu zero' "$BASE/sem-controle.txt" || falhou "sem o controle, a saida nao diz que o controle deu zero"

grep '\[error\]' "$BASE/site.access.log" > "$BASE/so-erro.log"
sh "$CONTA" "$BASE/so-erro.log" > "$BASE/so-erro.txt" 2>&1
codigo=$?
[ "$codigo" = 2 ] || falhou "so com o log de erro: saiu com $codigo, e o esperado era 2"

sh "$CONTA" "$BASE/site.access.log" "$BASE/nao-existe-*.log" > "$BASE/sem-arquivo.txt" 2>&1
codigo=$?
[ "$codigo" = 2 ] || falhou "com um arquivo que nao existe (o glob literal): saiu com $codigo, e o esperado era 2"

printf 'isto nao e gzip\n' > "$BASE/quebrado.log.3.gz"
sh "$CONTA" "$BASE/site.access.log" "$BASE/quebrado.log.3.gz" > "$BASE/quebrado.txt" 2>&1
codigo=$?
[ "$codigo" = 2 ] || falhou "com um .gz que nao se le: saiu com $codigo, e o esperado era 2"

# --- 6: o procedimento manda rodar, e o comando dele funciona ---------------
# O COMANDO, e nao a frase da tabela: dos blocos `bash` de "O que hoje
# bloqueia", sem o comentario do shell e com as linhas continuadas juntas, a do
# `ssh` que manda o roteiro pela entrada do `sh -s` e os logs pelos argumentos.
# E ela RODA aqui: o que vai entre aspas para a producao, num `sh -c`, com o
# `/var/log/nginx/` trocado por um diretorio com o log inventado, um girado em
# texto e um `.gz` -- e tem de dar o mesmo que a conta chamada direto sobre os
# tres. Sem os argumentos, o `sh -s` le o resto do proprio roteiro como log; sem
# o `*.log.*`, os girados ficam de fora: os dois dao outro numero.
awk '/^### O que hoje bloqueia/ { dentro = 1; next }
     dentro && /^### / { exit }
     dentro && /^```bash/ { codigo = 1; next }
     dentro && codigo && /^```/ { codigo = 0; next }
     dentro && codigo { print }' "$PROCEDIMENTO" \
    | awk '{ sub(/^[ \t]*#.*$/, ""); sub(/[ \t]#.*$/, "")
             if (sub(/\\$/, "")) { junta = junta $0; next }
             print junta $0; junta = "" }' > "$BASE/comandos.sh"
linha=$(grep -E "^[[:space:]]*ssh .* 'sh -s -- [^']+'[[:space:]]*<[[:space:]]*scripts/medir-chamadas-unidade-vendas\.sh([[:space:]]|$)" "$BASE/comandos.sh" | head -1)
remoto=$(printf '%s\n' "$linha" | sed -n "s/^[[:space:]]*ssh .* '\(sh -s -- [^']*\)'.*/\1/p")
if [ -z "$remoto" ]; then
    falhou "\"O que hoje bloqueia\" do $PROCEDIMENTO nao tem mais, num bloco bash e fora de comentario, o ssh que manda scripts/medir-chamadas-unidade-vendas.sh pela entrada do sh -s e os logs pelos argumentos (a resposta 33 do dono)"
else
    case $remoto in
        *'/var/log/nginx/'*) ;;
        *) falhou "o comando do procedimento ($remoto) nao le /var/log/nginx/, onde mora o log de cada vhost (o D36)" ;;
    esac
    mkdir -p "$BASE/nginx"
    cp "$BASE/site.access.log" "$BASE/nginx/site.access.log"
    cp "$BASE/www.site.access.log.2.gz" "$BASE/nginx/site.access.log.2.gz"
    cat > "$BASE/nginx/site.access.log.1" <<FIM
192.0.2.30 - - [04/Oct/2026:12:00:00 -0300] "GET /api/versao/app HTTP/1.1" 200 77 "-" "$UA"
192.0.2.30 - - [04/Oct/2026:12:01:00 -0300] "GET /api/unidade/vendasV2?id=7&hash=$H HTTP/1.1" 200 2048 "-" "$UA"
FIM
    aqui=$(printf '%s\n' "$remoto" | sed "s|/var/log/nginx/|$BASE/nginx/|g")
    sh -c "$aqui" < "$CONTA" > "$BASE/pelo-ssh.txt" 2>&1
    codigo=$?
    sh "$CONTA" "$BASE"/nginx/*.log "$BASE"/nginx/*.log.* > "$BASE/direto.txt" 2>&1
    [ "$codigo" = 0 ] || falhou "o comando do procedimento, rodado aqui sobre os logs inventados ($aqui), saiu com $codigo ($(tail -1 "$BASE/pelo-ssh.txt"))"
    pelo_ssh=$(awk '$1 == "total" { print $2, $3, $4, $5, $6 }' "$BASE/pelo-ssh.txt")
    direto=$(awk '$1 == "total" { print $2, $3, $4, $5, $6 }' "$BASE/direto.txt")
    [ "$direto" = '8 5 2 2 5' ] || falhou "a conta direta sobre os tres logs do diretorio deu \"$direto\"; o esperado era \"8 5 2 2 5\""
    [ "$pelo_ssh" = "$direto" ] || falhou "o comando do procedimento deu \"$pelo_ssh\", e a conta direta sobre os mesmos tres logs, \"$direto\": o comando nao le os logs que a conta le (o girado, o .gz, os argumentos do sh -s)"
fi

if [ "$falhas" -gt 0 ]; then
    echo "A CONTA DAS unidadeVendas* NAO CONTA O QUE DIZ ($falhas):"
    exit 1
fi
echo "ok: a conta das tres unidadeVendas* conta por dia e por caminho, deixa de fora o que nao e pedido a elas, nao imprime IP, hash nem query, e diz quando nao mediu"
exit 0
