import {
  assertFails,
  initializeTestEnvironment,
  RulesTestEnvironment,
} from '@firebase/rules-unit-testing';
import { readFileSync } from 'node:fs';
import { doc, getDoc, setDoc } from 'firebase/firestore';

/**
 * `MG-1` — a infraestrutura de teste de security rule funciona, e as rules
 * começam **fechadas**.
 *
 * Este arquivo não testa regra de negócio: testa que dá para testar regra. É o
 * que `MG-2` e `MG-3` vão usar para verificar participação, sigilo e prazo — e
 * sem provar isso agora, aquelas stories começariam sem chão.
 */
describe('MG-1 — rules começam fechadas', () => {
  let ambiente: RulesTestEnvironment;

  beforeAll(async () => {
    ambiente = await initializeTestEnvironment({
      projectId: 'demo-bolao',
      firestore: {
        rules: readFileSync(`${__dirname}/../../firestore.rules`, 'utf8'),
        host: '127.0.0.1',
        port: 8080,
      },
    });
  });

  afterAll(async () => {
    await ambiente.cleanup();
  });

  beforeEach(async () => {
    await ambiente.clearFirestore();
  });

  it('participante autenticado não lê nada antes de MG-2', async () => {
    const db = ambiente.authenticatedContext('ana').firestore();
    // Abrir primeiro e fechar depois é como um vazamento entra em produção: o
    // estado intermediário parece funcionar.
    await assertFails(getDoc(doc(db, 'boloes/p1')));
  });

  it('participante autenticado não escreve nada antes de MG-2', async () => {
    const db = ambiente.authenticatedContext('ana').firestore();
    await assertFails(setDoc(doc(db, 'boloes/p1'), { nome: 'Bolão' }));
  });

  it('anônimo também não passa', async () => {
    const db = ambiente.unauthenticatedContext().firestore();
    await assertFails(getDoc(doc(db, 'boloes/p1')));
  });

  it('o contexto privilegiado do teste escreve — é como o cenário é montado', async () => {
    // `withSecurityRulesDisabled` é o que permite semear dado para testar
    // leitura. Sem isso, todo teste de rule de leitura ficaria sem fixture.
    await ambiente.withSecurityRulesDisabled(async (contexto) => {
      await setDoc(doc(contexto.firestore(), 'boloes/p1'), { nome: 'Bolão' });
    });
    const db = ambiente.authenticatedContext('ana').firestore();
    await assertFails(getDoc(doc(db, 'boloes/p1')));
  });
});
