#!/usr/bin/env bash
#
# Roda a suite de CONTRATO contra o POSTGRESQL.
#
#     sh scripts/rodar-contrato-postgres.sh
#
# POR QUE ISTO EXISTE. O contrato do aplicativo -- o que os aparelhos
# instalados esperam receber, e que ninguem pode atualizar em bloco (D5) --
# so era conferido contra MySQL. A migracao e para o PostgreSQL.
#
# E ja se sabe que a diferenca entre os dois nao e teorica: em 05/09/2026 o
# `SaldoDuplicadoTest` ficou VERDE no MySQL e VERMELHO no PostgreSQL com o mesmo
# codigo, porque o InnoDB devolve a ordem da chave primaria e o PostgreSQL
# devolve a ordem de gravacao (D72). Se isso acontece na caracterizacao, pode
# acontecer numa resposta que o aplicativo le.
#
# O que este roteiro responde e uma pergunta so, e ela vale ser respondida antes
# do corte: TROCAR O BANCO MUDA O QUE O APLICATIVO RECEBE?
#
# ---------------------------------------------------------------------------
# ELE NAO SUBSTITUI O `rodar-contrato.sh`.
#
# Aquele roda contra MySQL, que e o que esta em producao hoje. Os dois precisam
# passar: um diz que o contrato nao regrediu, o outro que ele nao depende do
# banco.
#
# ---------------------------------------------------------------------------
# A CONFERENCIA DE BANCO DA SUITE PASSA AQUI, e nao por acaso.
#
# `ContratoTestCase::exigirBancoDeFixtures` recusa banco com dado real, e
# reconhece isso pelos IDS das unidades (faixa 90000000+), nao pelo nome do
# banco. Um banco montado de `postgres/schema.sql` mais as fixtures satisfaz a
# checagem naturalmente.

set -euo pipefail

BANCO="franquiabv_pgcontrato"
LOCAL="config/autoload/local.php"
BACKUP="$(mktemp)"

if [ ! -f "$LOCAL" ]; then
    echo "nao achei $LOCAL -- rode a partir da raiz do projeto." >&2
    exit 2
fi

if grep -q "'dbname' => '${BANCO}'" "$LOCAL"; then
    echo "O local.php JA APONTA para ${BANCO}." >&2
    echo "  Uma execucao anterior nao restaurou o ambiente. Aponte-o de volta antes." >&2
    exit 2
fi

cp "$LOCAL" "$BACKUP"

restaurar() {
    cp "$BACKUP" "$LOCAL"
    rm -f "$BACKUP"
    docker compose exec -T app sh -c 'rm -rf data/DoctrineORMModule/Proxy/* data/cache/*; true' >/dev/null 2>&1 || true
    echo
    echo "ambiente restaurado: $(grep -m1 dbname "$LOCAL" | tr -d ' ')"

    if grep -q "'dbname' => '${BANCO}'" "$LOCAL"; then
        echo "  ATENCAO: o local.php CONTINUA apontando para ${BANCO}." >&2
    fi
}
trap restaurar EXIT INT TERM

echo "montando ${BANCO} a partir de postgres/schema.sql mais as fixtures..."

docker compose exec -T postgres psql -U franquiabv -d postgres -q \
    -c "DROP DATABASE IF EXISTS ${BANCO};" -c "CREATE DATABASE ${BANCO};" >/dev/null

docker compose exec -T postgres psql -U franquiabv -d "${BANCO}" -q -v ON_ERROR_STOP=1 -f - \
    < postgres/schema.sql >/dev/null

# A CARGA FALHA ALTO -- ver o cabecalho do `rodar-caracterizacao-postgres.sh`.
# `SET app.inquilino_id` porque o RLS exige; `SET NAMES` fora porque e do MySQL.
{
    echo "SET app.inquilino_id = 1;"
    grep -v "^SET NAMES" tests/Caracterizacao/fixtures.sql
} | docker compose exec -T postgres psql -U franquiabv -d "${BANCO}" -q -v ON_ERROR_STOP=1 -f -

# AS SEQUENCIAS PRECISAM SER AVANCADAS DEPOIS DAS FIXTURES.
#
# `fixtures.sql` grava com id explicito, e no PostgreSQL isso NAO move a
# sequencia. A primeira insercao feita pela aplicacao pede o id 1, acha o
# cliente avulso no lugar e responde 500 -- foi o que o cadastro da quarta
# fatia encontrou. O MySQL nao tem o problema: o AUTO_INCREMENT sobe
# sozinho quando alguem grava um id maior.
docker compose exec -T postgres psql -U franquiabv -d "${BANCO}" -q -v ON_ERROR_STOP=1 -f - \
    < postgres/repontar-sequencias.sql

sed -e "s/'dbname' *=> *'[a-z_]*'/'dbname' => '${BANCO}'/" \
    config/autoload/local.postgres.php.dist > "$LOCAL"

docker compose exec -T app sh -c 'rm -rf data/DoctrineORMModule/Proxy/* data/cache/*; true'

# O OPCACHE MEDE O PASSADO: o php-fpm ainda serve o `local.php` de antes por
# ate ~3 s depois da troca, e o primeiro arquivo da suite ia ao banco velho
# (o vermelho do aparelho, nas fatias 76d e 81). Ver `esperar-o-opcache.sh`.
sh scripts/esperar-o-opcache.sh

# A senha e o token do usuario de fixture, como no roteiro do MySQL (D59).
# DEPOIS do sed: o roteiro acha o banco pelo `local.php`.
docker compose exec -T app php scripts/definir-senha-contrato.php

echo
echo "rodando a suite de contrato contra ${BANCO}..."
echo

docker compose exec -T app phpunit --testsuite contrato
