import { Client } from 'pg';

/**
 * URL do banco **de teste**, derivada da de desenvolvimento.
 *
 * Existe porque `dev` e `test` compartilhavam o mesmo banco, e isso custou
 * confiança no gate: mexer nos dados de desenvolvimento perturbava uma execução
 * da suíte, o cron do servidor de desenvolvimento mexia nas linhas que a suíte
 * estava afirmando, e depois de 07/08 esse cron passou a trazer **placar real**
 * no meio de um teste.
 *
 * `DATABASE_URL_TEST` sobrescreve, se alguém quiser apontar para outro lugar.
 */
export function urlDoBancoDeTeste(): string {
  const explicita = process.env.DATABASE_URL_TEST;
  if (explicita) return explicita;

  const dev = process.env.DATABASE_URL;
  if (!dev) {
    throw new Error(
      'DATABASE_URL não definida — a suíte precisa dela para derivar o banco de teste',
    );
  }

  const url = new URL(dev);
  // `/bolao` → `/bolao_test`. Sufixo em vez de nome fixo para respeitar quem
  // usa outro nome de banco.
  const nome = url.pathname.replace(/^\//, '') || 'bolao';
  if (nome.endsWith('_test')) return dev;
  url.pathname = `/${nome}_test`;
  return url.toString();
}

/** Nome do banco dentro da URL. */
export function nomeDoBanco(url: string): string {
  return new URL(url).pathname.replace(/^\//, '');
}

/**
 * Cria o banco de teste se ele não existir.
 *
 * Conecta na base administrativa `postgres` porque não se cria um banco estando
 * dentro dele.
 */
export async function criarBancoSeFaltar(urlTeste: string): Promise<void> {
  const alvo = nomeDoBanco(urlTeste);
  const admin = new URL(urlTeste);
  admin.pathname = '/postgres';

  const cliente = new Client({ connectionString: admin.toString() });
  await cliente.connect();
  try {
    const { rowCount } = await cliente.query(
      'select 1 from pg_database where datname = $1',
      [alvo],
    );
    if (rowCount === 0) {
      // Nome vem do próprio ambiente, não de entrada de usuário; ainda assim,
      // identificador entre aspas para não depender de case nem de caractere.
      await cliente.query(`create database "${alvo}"`);
    }
  } finally {
    await cliente.end();
  }
}
