#!/usr/bin/env bash
#
# O `deploy-teste.sh conferir` mede o Google no loopback no teste de sempre, e so
# o tira da medida quando o arquivo do Firebase esta no COMPOSE_FILE?
#
#     bash scripts/ensaiar-hosts-mortos-do-deploy.sh
#     bash scripts/ensaiar-hosts-mortos-do-deploy.sh <copia do scripts/deploy-teste.sh>
#
# Sai com 0 quando todo caso abaixo da a saida esperada; 1 quando algum nao da, e
# diz qual; 2 quando nao consegue medir (as listas ou as funcoes nao estao onde
# deviam, ou o duble do conteiner nao entendeu a pergunta). O argumento aponta o
# ensaio para uma COPIA do roteiro -- e como se falsifica sem tocar no de verdade.
#
# ---------------------------------------------------------------------------
# POR QUE ISTO EXISTE (11/10/2026, a verificacao do PUSH-TERCEIRA-RODADA; D461)
#
# Para o teste falar com o Google (a resposta 74 do dono), `fcm.googleapis.com`
# e `oauth2.googleapis.com` sairam de HOSTS_MORTOS: com o
# docker-compose.teste-firebase.yml ligado, o `conferir` os exigiria no loopback
# e nunca passaria. Mas o `conferir_hosts_mortos` so percorria HOSTS_MORTOS, e o
# teste de sempre -- sem o arquivo, com o Google cortado pelo
# docker-compose.teste.yml e pela homologacao -- deixou de ter o corte do Google
# medido no conteiner: o app nao recriado, ou a lista do teste sem um dos nomes
# no BVIP, passavam verdes. Quem segurava era so o portao de arquivos
# (`conferir-provedores-no-loopback.php`), que roda no repositorio e nao no
# servidor. Agora a funcao mede tambem os dois do Google (HOSTS_DO_GOOGLE)
# sempre que o COMPOSE_FILE do .env nao traz o arquivo do Firebase. Este ensaio
# e o caso que pega a volta do defeito: rodado contra o roteiro de antes, o caso
# "o teste de sempre com o Google aberto" sai verde, e o ensaio sai 1.
#
# ---------------------------------------------------------------------------
# COMO
#
# Tira do roteiro, inteiros, as tres linhas (HOSTS_MORTOS, HOSTS_DO_GOOGLE e
# ARQUIVO_DO_FIREBASE), o `do_env` e o `conferir_hosts_mortos`, e os roda sob o
# mesmo `set -euo pipefail` do roteiro, num diretorio temporario com o `.env` de
# cada caso. O `dc` e um duble: ao `getent` de cada nome ele responde com o
# loopback (127.0.0.1 e ::1), com um endereco de fora para os nomes ABERTOS do
# caso, ou com nada para os MUDOS, e anota a pergunta. O `falhar` e o `ok` so
# escrevem. Os casos:
#
#   o teste de sempre (o COMPOSE_FILE do .env.teste.example):
#     tudo no loopback                    sai 0, e perguntou por cada nome de
#                                         HOSTS_MORTOS e de HOSTS_DO_GOOGLE
#     cada nome aberto, um de cada vez    sai 1, dizendo o nome (os do Google
#                                         entre eles: e o defeito de 11/10)
#     o Google mudo                       sai 1 (a resposta vazia reprova)
#   com o arquivo do Firebase no fim do COMPOSE_FILE (com e sem aspas):
#     o Google aberto                     sai 0
#     o Google aberto e cada nome de      sai 1, dizendo o nome: o arquivo so
#     HOSTS_MORTOS aberto, um de cada vez tira o Google da medida
#
# O QUE ELE NAO AFIRMA: nada do BVIP nem de conteiner nenhum -- o `getent` e o
# do duble. Que o conteiner de la tenha a lista certa, so o `conferir` rodado la.
# E que a lista de HOSTS_DO_GOOGLE seja a do portao: isso o
# `conferir-provedores-no-loopback.php` confere.

set -u

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

DEPLOY="${1:-scripts/deploy-teste.sh}"
[ -r "$DEPLOY" ] || { echo "NAO CONSEGUI MEDIR: nao li $DEPLOY" >&2; exit 2; }

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

nao_medi() { echo "NAO CONSEGUI MEDIR: $1" >&2; exit 2; }

# As tres linhas, cada uma uma vez so.
for nome in HOSTS_MORTOS HOSTS_DO_GOOGLE ARQUIVO_DO_FIREBASE; do
    [ "$(grep -cE "^$nome=\"[^\"]*\"\$" "$DEPLOY")" = 1 ] \
        || nao_medi "esperava UMA linha $nome=\"...\" em $DEPLOY."
done
grep -E '^(HOSTS_MORTOS|HOSTS_DO_GOOGLE|ARQUIVO_DO_FIREBASE)="[^"]*"$' "$DEPLOY" > "$T/listas.sh"
# shellcheck disable=SC1091
. "$T/listas.sh"
[ "$(printf '%s' "$HOSTS_MORTOS" | wc -w)" -ge 5 ] || nao_medi "HOSTS_MORTOS tem menos de cinco nomes."
[ -n "$HOSTS_DO_GOOGLE" ] || nao_medi "HOSTS_DO_GOOGLE esta vazia."
[ -f "$RAIZ/$ARQUIVO_DO_FIREBASE" ] || nao_medi "ARQUIVO_DO_FIREBASE ($ARQUIVO_DO_FIREBASE) nao existe na raiz do repositorio."

# As duas funcoes, inteiras: da linha `nome() {` a primeira `}` sozinha.
extrair() {
    awk -v nome="$1" '
        $0 == nome "() {" { dentro = 1 }
        dentro { print }
        dentro && $0 == "}" { achou = 1; exit }
        END { if (!achou) exit 1 }
    ' "$DEPLOY"
}
extrair do_env > "$T/do_env.sh" || nao_medi "nao achei a funcao do_env em $DEPLOY."
extrair conferir_hosts_mortos > "$T/conferir.sh" || nao_medi "nao achei a funcao conferir_hosts_mortos em $DEPLOY."
grep -q 'dc exec' "$T/conferir.sh" || nao_medi "o conferir_hosts_mortos nao pergunta mais ao conteiner pelo dc exec: o duble nao sabe responder."

{
    echo 'set -euo pipefail'
    cat "$T/listas.sh"
    cat <<'FIM'
falhar() { printf 'ABORTADO: %s\n' "$*" >&2; exit 1; }
ok() { printf '    ok  %s\n' "$*"; }
# O duble do `dc exec -T app sh -c "getent hosts 'nome'; ..."`.
dc() {
    local pergunta="${!#}" h
    h=$(printf '%s' "$pergunta" | sed -n "s/^getent hosts '\([^']*\)'.*/\1/p")
    if [ "$1 $2 $3 $4" != "exec -T app sh" ] || [ -z "$h" ]; then
        printf '%s\n' "$*" >> "$ENSAIO_NAO_ENTENDI"
        return 0
    fi
    printf '%s\n' "$h" >> "$ENSAIO_PERGUNTAS"
    case " $ENSAIO_MUDOS " in *" $h "*) return 0 ;; esac
    case " $ENSAIO_ABERTOS " in
        *" $h "*) printf '142.250.79.10   %s\n2800:3f0:4001:810::200a %s\n' "$h" "$h" ;;
        *) printf '127.0.0.1       %s\n::1             %s\n' "$h" "$h" ;;
    esac
}
FIM
    cat "$T/do_env.sh" "$T/conferir.sh"
    echo 'conferir_hosts_mortos'
} > "$T/rodar.sh"

: > "$T/nao-entendi.txt"
falhas=0
casos=0
falhou() { echo "  - $1"; falhas=$((falhas + 1)); }

SEMPRE='docker-compose.yml:docker-compose.homologacao.yml:docker-compose.teste.yml'

# caso <rotulo> <linha COMPOSE_FILE do .env> <abertos> <mudos> <saida esperada> <nome que a saida tem de dizer, ou ->
caso() {
    local rotulo="$1" linha="$2" abertos="$3" mudos="$4" esperada="$5" diz="$6" c
    casos=$((casos + 1))
    c="$T/caso-$casos"
    mkdir -p "$c"
    printf 'COMPOSE_PROJECT_NAME=franquiabv-teste\n%s\n' "$linha" > "$c/.env"
    : > "$c/perguntas.txt"
    (cd "$c" && ENSAIO_ABERTOS="$abertos" ENSAIO_MUDOS="$mudos" ENSAIO_PERGUNTAS="$c/perguntas.txt" \
        ENSAIO_NAO_ENTENDI="$T/nao-entendi.txt" bash "$T/rodar.sh") > "$c/saida.txt" 2>&1
    local codigo=$?
    if [ "$codigo" != "$esperada" ]; then
        falhou "$rotulo: saiu $codigo, e devia sair $esperada ($(tail -n 1 "$c/saida.txt"))"
    elif [ "$diz" != - ] && ! grep -qF "$diz" "$c/saida.txt"; then
        falhou "$rotulo: saiu $codigo, mas a saida nao diz $diz ($(tail -n 1 "$c/saida.txt"))"
    fi
    PERGUNTAS="$c/perguntas.txt"
}

# 1. O teste de sempre, tudo no loopback: 0, e cada um dos nomes perguntado.
caso 'o teste de sempre, tudo no loopback' "COMPOSE_FILE=$SEMPRE" '' '' 0 -
for h in $HOSTS_MORTOS $HOSTS_DO_GOOGLE; do
    grep -qx "$h" "$PERGUNTAS" || falhou "o teste de sempre, tudo no loopback: o conferir nao perguntou ao conteiner por $h"
done

# 2. O teste de sempre, cada nome aberto: 1, dizendo o nome.
for h in $HOSTS_MORTOS $HOSTS_DO_GOOGLE; do
    caso "o teste de sempre, $h aberto" "COMPOSE_FILE=$SEMPRE" "$h" '' 1 "$h"
done

# 3. O teste de sempre, o Google mudo: a resposta vazia reprova.
for h in $HOSTS_DO_GOOGLE; do
    caso "o teste de sempre, $h sem resposta" "COMPOSE_FILE=$SEMPRE" '' "$h" 1 "$h"
done

# 4. Com o arquivo do Firebase, o Google aberto: 0 (com e sem aspas no .env).
caso 'com o arquivo do Firebase, o Google aberto' "COMPOSE_FILE=$SEMPRE:$ARQUIVO_DO_FIREBASE" "$HOSTS_DO_GOOGLE" '' 0 -
caso 'com o arquivo do Firebase entre aspas, o Google aberto' "COMPOSE_FILE=\"$SEMPRE:$ARQUIVO_DO_FIREBASE\"" "$HOSTS_DO_GOOGLE" '' 0 -

# 5. Com o arquivo do Firebase, o Google aberto e cada nome de HOSTS_MORTOS
#    aberto: 1, dizendo o nome.
for h in $HOSTS_MORTOS; do
    caso "com o arquivo do Firebase, o Google e $h abertos" "COMPOSE_FILE=$SEMPRE:$ARQUIVO_DO_FIREBASE" "$HOSTS_DO_GOOGLE $h" '' 1 "$h"
done

if [ -s "$T/nao-entendi.txt" ]; then
    echo "NAO CONSEGUI MEDIR: o duble do conteiner nao entendeu a pergunta do conferir_hosts_mortos: $(head -n 1 "$T/nao-entendi.txt")" >&2
    exit 2
fi
if [ "$falhas" -gt 0 ]; then
    echo "O CONFERIR DO DEPLOY DE TESTE NAO MEDE O LOOPBACK COMO DEVE ($DEPLOY): $falhas de $casos caso(s)"
    exit 1
fi
echo "ok: os $casos casos -- o teste de sempre mede os $(printf '%s' "$HOSTS_MORTOS $HOSTS_DO_GOOGLE" | wc -w | tr -d ' ') nomes, com o Google; com o $ARQUIVO_DO_FIREBASE, so o Google sai da medida"
exit 0
