#!/bin/sh
#
# O ensaio geral do corte roda a suite nos CLONES, e nao nas origens, devolve o
# local.php, e as guardas dele seguram?
#
#     sh scripts/ensaiar-clones-do-ensaio-de-corte.sh
#     sh scripts/ensaiar-clones-do-ensaio-de-corte.sh <copia do scripts/ensaiar-corte.sh>
#
# Sai com 0 quando todo caso abaixo da o esperado; 1 quando algum nao da, e diz
# qual; 2 quando nao consegue medir (falta `mktemp`, `bash` ou `cmp`, o roteiro
# perdeu uma das fases que este ensaio conhece, ou um duble ouviu um comando que
# nao sabe responder). 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 RESPOSTAS-SEM-RODADA; D378)
#
# O D378 levou a suite do `ensaiar-corte.sh` para dois clones -- o do
# PostgreSQL carregado, por TEMPLATE, e o do MySQL, por dump --, com as
# fixtures so neles. A prova foi um roteiro de rascunho, sobre bancos
# descartaveis, que ninguem roda de novo: desfazer qualquer parte do conserto
# (a suite da volta atras de volta a origem, as fixtures na origem, o trap de
# antes) deixava o repositorio inteiro verde. E a verificacao achou tres furos
# que so aparecem com o roteiro rodando inteiro: o local.php do clone do MySQL,
# deixado por uma execucao morta a forca, passava pela guarda do `apontar` e ia
# por cima do guardado bom; o `apagar_clones` deixava o GRANT do clone; e um
# `CLONE_MYSQL` com o nome de outro banco vivo o apagava.
#
# ---------------------------------------------------------------------------
# COMO
#
# Roda o roteiro INTEIRO, com `sh`, num diretorio temporario que tem so o que
# ele le: um `config/autoload/local.php` e um `local.postgres.php.dist` de
# mentira, fixtures e SQL de mentira (uma linha `MARCA:` cada) e os roteiros de
# `scripts/` que ele chama, como dubles que anotam. O `docker` e o `php` do PATH
# sao dubles: anotam cada pedido com o banco do `local.php` daquele instante, o
# banco pedido e a marca do que veio pela entrada, e respondem o minimo -- o
# `psql` guarda as configuracoes que o `ALTER DATABASE` grava (e o TEMPLATE nao
# copia, como no PostgreSQL de verdade), e o dump do MySQL roda o texto do
# proprio roteiro, com o `pipefail` dele, sobre um `mysqldump` e um `mysql` de
# mentira. Nada sai do diretorio: o projeto do compose e um nome que nao existe,
# e o duble nunca chama o `docker` de verdade. Os casos:
#
#   o ensaio inteiro, verde        sai 0: as fixtures vao SO aos clones, a suite
#                                  roda duas vezes, cada uma no local.php do seu
#                                  clone, o conferidor da volta atras le a
#                                  origem, o criar-papeis roda no clone, o
#                                  clone so apaga o clone, o GRANT sai, os
#                                  vereditos tem as duas formas do PHPUnit 10, e
#                                  o local.php termina igual, byte a byte
#   a suite vermelha num clone     sai 1, e o local.php termina igual
#   (um caso para cada banco)
#   o local.php de um clone, ou    sai 1 antes de qualquer fase: nenhum pedido
#   do PostgreSQL, de uma          ao docker, o guardado e o local.php ficam
#   execucao morta                 como estavam
#   o local.php trocado durante    a fase `apontar` recusa, e nada e guardado
#   a carga (outro processo)       nem desfeito
#   a recusa do nome do banco,     sai 1, sem pedido nenhum e sem escrever no
#   com o guardado velho de outra  local.php
#   execucao
#   o CLONE_* do ambiente          ignorado: o ensaio so apaga `<banco>_suite`
#   o dump que morre no meio       derruba a `clone_mysql`, e a suite da volta
#                                  atras nao roda
#   a configuracao do banco que    derruba a `clone_pg`
#   o clone nao recebe
#   o local.php do modelo do       sai 0, com a suite nos dois clones, o GRANT
#   Docker (o do laboratorio, que  para o usuario do ambiente e o local.php
#   le a conexao do ambiente)      igual no fim (D469)
#   o mesmo modelo, com o banco    sai 1 antes de qualquer pedido
#   do ambiente que nao e o da
#   origem
#
# DESDE 08/11/2026 (o D469) o roteiro le o local.php pelo PHP do conteiner da
# aplicacao (`scripts/conexao-do-local-php.php`), e o duble do conteiner o
# avalia com o PHP de verdade e o ambiente de mentira de cada caso
# (`ENSAIO_AMBIENTE_DO_APP`): e o mesmo arquivo que o roteiro pede, lido como o
# conteiner o leria.
#
# O QUE ELE NAO AFIRMA: nada de banco nenhum. Que o TEMPLATE, o dump e o REVOKE
# fazem o que os dubles fingem, so os bancos dizem: o REVOKE IF EXISTS foi
# rodado no MySQL 8.4.11 daqui em 11/10/2026, e o resto na prova do D378, sobre
# bancos descartaveis. Nem o tempo e o disco dos clones no tamanho da producao.

set -u

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

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

ROTEIRO="${1:-scripts/ensaiar-corte.sh}"
[ -r "$ROTEIRO" ] || nao_medi "nao li $ROTEIRO"
ROTEIRO="$(cd "$(dirname "$ROTEIRO")" && pwd)/$(basename "$ROTEIRO")"

for f in clone_pg clone_mysql apagar_clones caracterizacao volta_atras apontar; do
    grep -qE "^fase +$f " "$ROTEIRO" || nao_medi "o roteiro nao tem mais a fase $f: este ensaio nao sabe o que ele faz."
done

command -v bash > /dev/null 2>&1 || nao_medi "sem bash (os dubles sao bash)."
command -v cmp > /dev/null 2>&1 || nao_medi "sem cmp."
# O PHP DE VERDADE, para o duble do conteiner da aplicacao avaliar o local.php
# como o PHP de la (o `scripts/conexao-do-local-php.php`, o D469). O `php` do
# PATH dos casos e o duble do host.
PHP_DE_VERDADE=$(command -v php 2>/dev/null) || nao_medi "sem php (o local.php e avaliado por ele)."

T=$(mktemp -d 2>/dev/null) || nao_medi "mktemp -d falhou."
trap 'rm -rf "$T"' EXIT INT TERM
T=$(cd "$T" && pwd -P)

PROJ="ensaio-de-mentira-$$"
mkdir -p "$T/bin" "$T/bin-mysql"
: > "$T/nao-entendi.txt"

# ---------------------------------------------------------------------------
# Os dubles.
# ---------------------------------------------------------------------------

cat > "$T/bin/docker" <<'FIM'
#!/usr/bin/env bash
# O duble do `docker` deste ensaio. Anota, responde o minimo, e nunca chama o de verdade.
set -u
EV="$ENSAIO_EVENTOS"
ESTADO="$ENSAIO_ESTADO"

nao_entendi() { printf '%s\n' "$*" >> "$ENSAIO_NAO_ENTENDI"; exit 0; }
# O LOCAL.PHP COMO O PHP DO CONTEINER O LE (D469): avaliado, com o ambiente do
# conteiner de mentira (ENSAIO_AMBIENTE_DO_APP) -- o `getenv` do modelo do Docker
# le dali. `conexao` e o que o roteiro pede; `do_local` e o que o duble anota.
conexao() {
    env $ENSAIO_AMBIENTE_DO_APP "$ENSAIO_PHP" "$ENSAIO_RAIZ/scripts/conexao-do-local-php.php" "${1:-config/autoload/local.php}"
}
do_local() {
    case "$1" in host) campo=1 ;; dbname) campo=2 ;; *) campo=3 ;; esac
    conexao 2>/dev/null | cut -d'|' -f "$campo"
}

case "${1:-}" in
    info) echo 4; exit 0 ;;
    inspect) echo 0; exit 0 ;;
    compose) shift ;;
    *) nao_entendi "docker $*" ;;
esac

[ "${1:-}" = -p ] && [ "${2:-}" = "$ENSAIO_PROJETO" ] || nao_entendi "docker compose $*"
shift 2
[ "${1:-} ${2:-}" = "exec -T" ] || nao_entendi "docker compose -p $ENSAIO_PROJETO $*"
shift 2
servico=$1
shift

entrada="$ESTADO/entrada.$$"
cat > "$entrada"
marca=$(sed -n 's/.*MARCA:\([a-z_0-9]*\).*/\1/p' "$entrada" | head -1)

case "$servico" in
app)
    host=$(do_local host)
    banco=$(do_local dbname)
    case "${1:-}" in
        phpunit)
            echo "phpunit|$host|$banco" >> "$EV"
            case " ${ENSAIO_SUITE_FALHA:-} " in
                *" $host "*) printf 'FAILURES!\nTests: 7, Assertions: 14, Failures: 1.\n'; exit 1 ;;
            esac
            printf 'OK, but some tests were skipped!\nTests: 7, Assertions: 14, Skipped: 3.\n'
            exit 0
            ;;
        php)
            case "${2:-}" in
                # A leitura da conexao nao anota: e leitura, e as recusas do
                # comeco a fazem antes de "nenhum pedido".
                scripts/conexao-do-local-php.php) conexao "${3:-config/autoload/local.php}"; exit $? ;;
                scripts/conferir-vigencia-do-horario.php) echo "vigencia_conferir|$host|$banco|${3:-}" >> "$EV"; exit 0 ;;
                scripts/ensaiar-vigencia-do-horario.php) echo "vigencia_ensaiar|$host|$banco|${3:-}" >> "$EV"; exit 0 ;;
            esac
            ;;
        sh)
            case "${3:-}" in
                "rm -rf data/DoctrineORMModule/Proxy/"*) echo "proxies|$host|$banco" >> "$EV"; exit 0 ;;
            esac
            ;;
    esac
    nao_entendi "app $*"
    ;;
postgres)
    [ "${1:-}" = psql ] || nao_entendi "postgres $*"
    shift
    banco=''
    sqls=()
    while [ $# -gt 0 ]; do
        case "$1" in
            -d) banco=$2; shift 2 ;;
            -U|-v|-f) shift 2 ;;
            -c) sqls+=("$2"); shift 2 ;;
            -q|-tA) shift ;;
            *) nao_entendi "psql com $1" ;;
        esac
    done
    if [ -n "$marca" ]; then
        echo "carga|postgres|$banco|$marca" >> "$EV"
        case "$marca" in
            schema)
                printf 'search_path=bvip, public\ntimezone=America/Sao_Paulo\n' > "$ESTADO/pg-config-$banco"
                [ -z "${ENSAIO_CONFIG_EXTRA:-}" ] || echo 'work_mem=64MB' >> "$ESTADO/pg-config-$banco"
                ;;
            semente_pg) echo 0 ;;
        esac
    fi
    for s in ${sqls[@]+"${sqls[@]}"}; do
        case "$s" in
            *"FROM pg_db_role_setting"*)
                alvo=$(printf '%s' "$s" | sed -n "s/.*d\.datname = '\([^']*\)'.*/\1/p")
                if [ -f "$ESTADO/pg-config-$alvo" ]; then
                    sort "$ESTADO/pg-config-$alvo" | tr '\n' '|' | sed 's/|$//'
                    echo
                else
                    echo
                fi
                ;;
            "CREATE DATABASE "*)
                echo "sql|postgres|$s" >> "$EV"
                nome=$(printf '%s' "$s" | sed -n 's/^CREATE DATABASE "\([^"]*\)".*/\1/p')
                : > "$ESTADO/pg-config-$nome"
                ;;
            "DROP DATABASE "*)
                echo "sql|postgres|$s" >> "$EV"
                ;;
            "ALTER DATABASE "*)
                echo "sql|postgres|$s" >> "$EV"
                nome=$(printf '%s' "$s" | sed -n 's/^ALTER DATABASE "\([^"]*\)".*/\1/p')
                printf '%s\n' "$s" | sed -n 's/^ALTER DATABASE "[^"]*" SET \([a-z_]*\) = \(.*\);$/\1=\2/p' | tr -d "'" >> "$ESTADO/pg-config-$nome"
                ;;
            "DROP SCHEMA "*) ;;
            SELECT*|SHOW*) echo 1 ;;
            *) nao_entendi "psql -c $s" ;;
        esac
    done
    exit 0
    ;;
mysql)
    case "${1:-}" in
        mysql)
            shift
            banco=''
            sql=''
            while [ $# -gt 0 ]; do
                case "$1" in
                    -e) sql=$2; shift 2 ;;
                    -*) shift ;;
                    *) banco=$1; shift ;;
                esac
            done
            [ -z "$marca" ] || echo "carga|mysql|$banco|$marca" >> "$EV"
            [ -n "$sql" ] || exit 0
            printf '%s\n' "$sql" | tr ';' '\n' | sed 's/^ *//' | while IFS= read -r s; do
                case "$s" in
                    '') ;;
                    "SELECT CONCAT(DEFAULT_CHARACTER_SET_NAME"*) echo 'utf8mb3 COLLATE utf8mb3_general_ci' ;;
                    SELECT*) echo 1 ;;
                    "DROP DATABASE "*|"CREATE DATABASE "*|"GRANT "*|"REVOKE "*) echo "sql|mysql|$s" >> "$EV" ;;
                    *) nao_entendi "mysql -e $s" ;;
                esac
            done
            exit 0
            ;;
        bash)
            # O DUMP: roda o texto do roteiro, com o `pipefail` que ele pedir, sobre
            # o `mysqldump` e o `mysql` de mentira.
            echo "dump" >> "$EV"
            PATH="$ENSAIO_BIN_MYSQL:$PATH" "$@" < /dev/null
            exit $?
            ;;
    esac
    nao_entendi "mysql $*"
    ;;
*)
    nao_entendi "servico $servico: $*"
    ;;
esac
FIM

cat > "$T/bin/php" <<'FIM'
#!/bin/sh
# O duble do `php` do host.
case "${1:-}" in
    scripts/gerar-ddl-postgres.php) echo "-- MARCA:schema" ;;
    scripts/conferir-migracao.php) echo "conferencia" >> "$ENSAIO_EVENTOS" ;;
    *) printf 'php %s\n' "$*" >> "$ENSAIO_NAO_ENTENDI" ;;
esac
FIM

cat > "$T/bin-mysql/mysqldump" <<'FIM'
#!/bin/sh
# O `mysqldump` de mentira: anota a origem (o ultimo argumento) e morre no meio se pedido.
for a in "$@"; do ultimo=$a; done
echo "mysqldump|$ultimo" >> "$ENSAIO_EVENTOS"
echo "-- MARCA:dump"
if [ -n "${ENSAIO_DUMP_MORRE:-}" ]; then
    echo "mysqldump: Got error: 1356 (de mentira)" >&2
    exit 2
fi
FIM

cat > "$T/bin-mysql/mysql" <<'FIM'
#!/bin/sh
# O `mysql` do fim do pipe do dump: le tudo e sai com 0.
for a in "$@"; do ultimo=$a; done
cat > /dev/null
echo "mysql_do_dump|$ultimo" >> "$ENSAIO_EVENTOS"
FIM

chmod +x "$T/bin/docker" "$T/bin/php" "$T/bin-mysql/mysqldump" "$T/bin-mysql/mysql"

[ "$(PATH="$T/bin:$PATH" command -v docker)" = "$T/bin/docker" ] || nao_medi "o duble do docker nao vem antes do de verdade no PATH."
[ "$(PATH="$T/bin:$PATH" command -v php)" = "$T/bin/php" ] || nao_medi "o duble do php nao vem antes do de verdade no PATH."

# ---------------------------------------------------------------------------
# O diretorio de cada caso.
# ---------------------------------------------------------------------------

# local_php <host> <dbname> <user>: um local.php de mentira, no formato do daqui.
local_php() {
    printf "<?php\nreturn ['doctrine' => ['connection' => ['orm_default' => ['params' => [\n"
    printf "                    'host' => '%s',\n                    'dbname' => '%s',\n                    'user' => '%s',\n" "$1" "$2" "$3"
    printf "]]]]];\n"
}

montar() {
    c=$1
    mkdir -p "$c/config/autoload" "$c/scripts" "$c/postgres" "$c/tests/Caracterizacao" "$c/estado"
    local_php mysql ens_copia ens_app > "$c/config/autoload/local.php"
    local_php postgres ens_copia bvip_app > "$c/config/autoload/local.postgres.php.dist"
    cp "$c/config/autoload/local.php" "$c/original.php"
    local_php mysql ens_copia_suite ens_app > "$c/clone-mysql.php"

    printf 'SET NAMES utf8mb4;\n-- MARCA:fixtures\n' > "$c/tests/Caracterizacao/fixtures.sql"
    echo '-- MARCA:limpeza' > "$c/scripts/pre-migracao-limpeza.sql"
    echo '-- MARCA:cep' > "$c/scripts/limpar-dicionario-cep.sql"
    echo '-- MARCA:lider' > "$c/scripts/migracao-grupo-lider-gerente.sql"
    echo '-- MARCA:semente_mysql' > "$c/scripts/semente-usuarios-horarios.mysql.sql"
    echo '-- MARCA:semente_pg' > "$c/postgres/semente-usuarios-horarios.sql"
    echo '-- MARCA:sequencias' > "$c/postgres/repontar-sequencias.sql"

    echo 'echo "papeis|$BANCO_PG" >> "$ENSAIO_EVENTOS"' > "$c/scripts/criar-papeis.sh"
    echo 'echo "provas_papeis" >> "$ENSAIO_EVENTOS"' > "$c/scripts/conferir-papeis.sh"
    cat > "$c/scripts/migrar-dados.sh" <<'FIM'
echo "carga_do_corte" >> "$ENSAIO_EVENTOS"
# OUTRO PROCESSO troca o local.php no meio da carga, se o caso pedir.
[ -z "${ENSAIO_LOCAL_NA_CARGA:-}" ] || cp "$ENSAIO_LOCAL_NA_CARGA" config/autoload/local.php
FIM
    : > "$c/eventos.txt"
}

# rodar <dir> [VAR=valor ...]: o roteiro inteiro, com os dubles; o codigo em $codigo.
rodar() {
    c=$1
    shift
    (cd "$c" && env PATH="$T/bin:$PATH" ENSAIO_EVENTOS="$c/eventos.txt" ENSAIO_ESTADO="$c/estado" \
        ENSAIO_NAO_ENTENDI="$T/nao-entendi.txt" ENSAIO_PROJETO="$PROJ" ENSAIO_BIN_MYSQL="$T/bin-mysql" \
        ENSAIO_PHP="$PHP_DE_VERDADE" ENSAIO_RAIZ="$RAIZ" \
        ENSAIO_AMBIENTE_DO_APP="DB_HOST=mysql DB_NAME=ens_copia DB_USER=ens_app" \
        PROJETO="$PROJ" SENHA_APP=de-mentira BANCO_MYSQL=ens_copia BANCO_PG=ens_copia USUARIO_PG=ens_dono \
        "$@" sh "$ROTEIRO" ensaio) < /dev/null > "$c/saida.txt" 2>&1
    codigo=$?
}

# ---------------------------------------------------------------------------
# As conferencias.
# ---------------------------------------------------------------------------

falhas=0
casos=0
caso=''
falhou() { echo "  - $caso: $1"; falhas=$((falhas + 1)); }

saiu() { [ "$codigo" = "$1" ] || falhou "saiu $codigo, e devia sair $1 ($(tail -n 1 "$c/saida.txt"))"; }
tem() { grep -qxF "$2" "$c/eventos.txt" || falhou "$1 (faltou: $2)"; }
nao_tem() { ! grep -qF "$2" "$c/eventos.txt" || falhou "$1 (veio: $(grep -F "$2" "$c/eventos.txt" | head -1))"; }
vezes() {
    n=$(grep -cxF "$2" "$c/eventos.txt")
    [ "$n" = "$3" ] || falhou "$1 ($2: $n vez(es), e devia $3)"
}
igual() { cmp -s "$2" "$3" || falhou "$1"; }
fase_falhou() { grep -qE "^$1 +FALHOU" "$c/ensaios/ensaio.txt" 2>/dev/null || falhou "a fase $1 devia ter falhado ($(tail -n 1 "$c/saida.txt"))"; }
nenhum_pedido() { [ ! -s "$c/eventos.txt" ] || falhou "devia parar antes de qualquer pedido, e pediu: $(head -1 "$c/eventos.txt")"; }
suites() { grep '^phpunit|' "$c/eventos.txt" | tr '\n' ' '; }
apagados() {
    grep -E '^sql\|(postgres|mysql)\|DROP DATABASE' "$c/eventos.txt" |
        sed -n 's/.*DROP DATABASE IF EXISTS ["`]\([^"`]*\)["`].*/\1/p' | sort -u | tr '\n' ' '
}

novo_caso() {
    casos=$((casos + 1))
    caso=$1
    c="$T/caso-$casos"
    montar "$c"
}

# 1. O ensaio inteiro, verde.
novo_caso 'o ensaio inteiro, verde'
rodar "$c"
saiu 0
vezes 'as fixtures do PostgreSQL vao ao clone, uma vez' 'carga|postgres|ens_copia_suite|fixtures' 1
vezes 'as fixtures do MySQL vao ao clone, uma vez' 'carga|mysql|ens_copia_suite|fixtures' 1
nao_tem 'nenhuma fixture na origem do PostgreSQL' 'carga|postgres|ens_copia|fixtures'
nao_tem 'nenhuma fixture na origem do MySQL' 'carga|mysql|ens_copia|fixtures'
tem 'as sequencias avancam no clone' 'carga|postgres|ens_copia_suite|sequencias'
tem 'o criar-papeis roda no clone do PostgreSQL' 'papeis|ens_copia_suite'
tem 'o dump sai da origem do MySQL' 'mysqldump|ens_copia'
tem 'e entra no clone' 'mysql_do_dump|ens_copia_suite'
[ "$(suites)" = 'phpunit|postgres|ens_copia_suite phpunit|mysql|ens_copia_suite ' ] ||
    falhou "a suite tem de rodar duas vezes, no clone do PostgreSQL e depois no do MySQL, e rodou: $(suites)"
tem 'o conferidor da volta atras le a origem do MySQL' 'vigencia_conferir|mysql|ens_copia|--plataforma=mysql'
tem 'o 7b le o PostgreSQL da carga' 'vigencia_conferir|postgres|ens_copia|--plataforma=postgresql'
nao_tem 'nenhuma vigencia le um clone' 'ens_copia_suite|--plataforma'
[ "$(apagados)" = 'ens_copia_suite ' ] || falhou "o ensaio so apaga o clone, e apagou: $(apagados)"
grep -E '^sql\|mysql\|(GRANT|REVOKE) ' "$c/eventos.txt" | tail -1 |
    grep -qxF "sql|mysql|REVOKE IF EXISTS ALL ON \`ens_copia_suite\`.* FROM 'ens_app'@'%'" ||
    falhou 'o GRANT do clone do MySQL sai no fim (o REVOKE, depois do ultimo GRANT)'
grep -qE '^portao_caracterizacao +Tests: 7, Assertions: 14, Skipped: 3$' "$c/ensaios/ensaio.txt" 2>/dev/null ||
    falhou 'o veredito da suite no clone do PostgreSQL, com caso pulado, vai ao registro'
grep -qE '^portao_volta_atras +Tests: 7, Assertions: 14, Skipped: 3$' "$c/ensaios/ensaio.txt" 2>/dev/null ||
    falhou 'o veredito da suite na volta atras, com caso pulado, vai ao registro'
igual 'o local.php termina igual ao de antes' "$c/original.php" "$c/config/autoload/local.php"

# 2 e 3. A suite vermelha num clone: o local.php termina igual.
for banco in postgres mysql; do
    novo_caso "a suite vermelha no clone do $banco"
    rodar "$c" ENSAIO_SUITE_FALHA="$banco"
    saiu 1
    if [ "$banco" = postgres ]; then fase_falhou caracterizacao; else fase_falhou volta_atras; fi
    igual 'o trap devolve o local.php de antes' "$c/original.php" "$c/config/autoload/local.php"
done

# 4 e 5. O local.php que uma execucao morta a forca deixa: o do clone do MySQL
# (o host e o mesmo da origem) e o do PostgreSQL. O guardado e o bom.
for deixado in clone-mysql postgres; do
    novo_caso "o local.php do $deixado, deixado por uma execucao morta"
    cp "$c/original.php" "$c/guardado-bom.php"
    mkdir -p "$c/ensaios"
    cp "$c/original.php" "$c/ensaios/local.mysql.guardado"
    if [ "$deixado" = postgres ]; then
        cp "$c/config/autoload/local.postgres.php.dist" "$c/config/autoload/local.php"
    else
        cp "$c/clone-mysql.php" "$c/config/autoload/local.php"
    fi
    cp "$c/config/autoload/local.php" "$c/deixado.php"
    rodar "$c"
    saiu 1
    nenhum_pedido
    igual 'o guardado bom fica como estava' "$c/guardado-bom.php" "$c/ensaios/local.mysql.guardado"
    igual 'e o local.php deixado tambem: o trap so desfaz o que este processo fez' "$c/deixado.php" "$c/config/autoload/local.php"
done

# 6. Outro processo troca o local.php durante a carga: a fase `apontar` recusa.
novo_caso 'o local.php trocado durante a carga'
rodar "$c" ENSAIO_LOCAL_NA_CARGA="$c/clone-mysql.php"
saiu 1
fase_falhou apontar
[ ! -e "$c/ensaios/local.mysql.guardado" ] || falhou 'nada e guardado: o local.php trocado iria por cima do guardado'
nao_tem 'a suite nao roda' 'phpunit|'
igual 'e o trap nao desfaz o que nao fez' "$c/clone-mysql.php" "$c/config/autoload/local.php"

# 7. As recusas do comeco, com o guardado velho de outra execucao e o local.php
# do PostgreSQL: o nome do banco, e o local.php que nao e o da origem.
for recusa in nome local; do
    novo_caso "a recusa do $recusa, com o guardado velho de outra execucao"
    mkdir -p "$c/ensaios"
    echo '<?php // o guardado velho de outra execucao' > "$c/ensaios/local.mysql.guardado"
    cp "$c/ensaios/local.mysql.guardado" "$c/guardado-velho.php"
    cp "$c/config/autoload/local.postgres.php.dist" "$c/config/autoload/local.php"
    if [ "$recusa" = nome ]; then
        rodar "$c" BANCO_MYSQL=ens-copia
    else
        rodar "$c"
    fi
    saiu 1
    grep -q 'ABORTADO' "$c/saida.txt" || falhou 'a saida diz ABORTADO'
    nenhum_pedido
    igual 'o local.php nao e escrito' "$c/config/autoload/local.postgres.php.dist" "$c/config/autoload/local.php"
    igual 'nem o guardado' "$c/guardado-velho.php" "$c/ensaios/local.mysql.guardado"
done

# 8. O CLONE_* do ambiente com o nome de outro banco vivo: ignorado.
novo_caso 'o CLONE_* do ambiente com o nome de outros bancos'
rodar "$c" CLONE_MYSQL=franquiabv_dev CLONE_PG=franquiabv_pgcontrato
saiu 0
[ "$(apagados)" = 'ens_copia_suite ' ] || falhou "so o <banco>_suite e apagado, e foram: $(apagados)"
nao_tem 'o franquiabv_dev nao e tocado' 'franquiabv_dev'
nao_tem 'nem o do contrato' 'franquiabv_pgcontrato'

# 9. O dump que morre no meio derruba a `clone_mysql`.
novo_caso 'o dump que morre no meio'
rodar "$c" ENSAIO_DUMP_MORRE=1
saiu 1
fase_falhou clone_mysql
nao_tem 'as fixtures nao vao ao clone pela metade' 'carga|mysql|ens_copia_suite|fixtures'
[ "$(suites)" = 'phpunit|postgres|ens_copia_suite ' ] || falhou "a suite da volta atras nao roda, e rodaram: $(suites)"
igual 'o local.php termina igual ao de antes' "$c/original.php" "$c/config/autoload/local.php"

# 10. Uma configuracao do banco que o TEMPLATE nao leva e a fase nao regrava.
novo_caso 'a configuracao da origem que o clone nao recebe'
rodar "$c" ENSAIO_CONFIG_EXTRA=1
saiu 1
fase_falhou clone_pg
nao_tem 'a suite nao roda num clone diferente da origem' 'phpunit|'
igual 'o local.php nao e tocado' "$c/original.php" "$c/config/autoload/local.php"

# 11. O local.php do laboratorio: o do `docker/config/local.php.docker`, que le
# a conexao do ambiente (D469). Antes de 08/11/2026 o ensaio parava no comeco
# com ele; agora vai inteiro, a suite le os clones e o local.php volta igual.
novo_caso 'o local.php do modelo do Docker, com o banco no ambiente'
cp "$RAIZ/docker/config/local.php.docker" "$c/config/autoload/local.php"
cp "$c/config/autoload/local.php" "$c/original.php"
rodar "$c"
saiu 0
[ "$(suites)" = 'phpunit|postgres|ens_copia_suite phpunit|mysql|ens_copia_suite ' ] ||
    falhou "a suite roda nos dois clones, e rodou: $(suites)"
vezes 'as fixtures do MySQL vao ao clone, uma vez' 'carga|mysql|ens_copia_suite|fixtures' 1
nao_tem 'nenhuma fixture na origem do MySQL' 'carga|mysql|ens_copia|fixtures'
tem 'o conferidor da volta atras le a origem do MySQL' 'vigencia_conferir|mysql|ens_copia|--plataforma=mysql'
grep -E '^sql\|mysql\|(GRANT|REVOKE) ' "$c/eventos.txt" | head -1 |
    grep -qF "TO 'ens_app'@'%'" || falhou 'o GRANT do clone e para o usuario do DB_USER'
[ "$(apagados)" = 'ens_copia_suite ' ] || falhou "o ensaio so apaga o clone, e apagou: $(apagados)"
igual 'o local.php termina igual ao de antes' "$c/original.php" "$c/config/autoload/local.php"

# 12. O mesmo modelo com o ambiente apontando para outro banco: a guarda do
# comeco le o banco do ambiente, e recusa antes de qualquer pedido.
novo_caso 'o modelo do Docker com o DB_NAME de outro banco'
cp "$RAIZ/docker/config/local.php.docker" "$c/config/autoload/local.php"
cp "$c/config/autoload/local.php" "$c/original.php"
rodar "$c" ENSAIO_AMBIENTE_DO_APP="DB_HOST=mysql DB_NAME=franquiabv_dev DB_USER=ens_app"
saiu 1
grep -q 'ABORTADO' "$c/saida.txt" || falhou 'a saida diz ABORTADO'
nenhum_pedido
igual 'o local.php nao e escrito' "$c/original.php" "$c/config/autoload/local.php"

# ---------------------------------------------------------------------------

if [ -s "$T/nao-entendi.txt" ]; then
    echo "NAO CONSEGUI MEDIR: os dubles ouviram pedidos que nao sabem responder:" >&2
    sort -u "$T/nao-entendi.txt" | head -5 | sed 's/-p[^ ]*/-p.../g; s/^/    /' >&2
    exit 2
fi

if [ "$falhas" -gt 0 ]; then
    echo "O ENSAIO DOS CLONES DO ENSAIO DE CORTE FALHOU: $falhas conferencia(s) em $casos casos."
    exit 1
fi

echo "Os clones do ensaio de corte: $casos casos, todos como deviam."
exit 0
