#!/usr/bin/env python3
"""Mapa de cobertura da migração (`MG-8 QA-1`).

Para cada caso dos planos da fase 1, diz **onde ele é verificado hoje**. Existe
como script, e não como tabela escrita à mão, por um motivo: tabela escrita à mão
envelhece em silêncio, e o risco desta story é justamente "os testes passam" sem
ninguém conferir quais.

Uso: `python3 docs/cobertura.py [--lista <categoria>]`
"""
import collections
import pathlib
import re
import subprocess
import sys

RAIZ = pathlib.Path(__file__).resolve().parent.parent
TESTES = RAIZ / 'docs' / 'testes'

ONDE = [
    ('firebase', RAIZ / 'bolao-firebase' / 'functions' / 'src'),
    ('app', RAIZ / 'bolao-mobile' / 'test'),
    ('device', RAIZ / 'bolao-mobile' / 'integration_test'),
]


def planos():
    """Casos da fase 1 e o mapa de origem declarado nos planos `MG-*`."""
    casos, origem = {}, collections.defaultdict(list)
    for p in sorted(TESTES.glob('*-plano.md')):
        for linha in p.read_text().split('\n'):
            cols = [c.strip() for c in linha.split('|')]
            if len(cols) < 4:
                continue
            cid = cols[1]
            if not re.fullmatch(r'[A-Z]{2}-\d+-\d+[a-z]?', cid):
                continue
            if cid.startswith('MG-'):
                de = cols[-2].strip('` ')
                if re.fullmatch(r'[A-Z]{2}-\d+-\d+[a-z]?', de):
                    origem[de].append(cid)
            else:
                casos[cid] = (cols[2], cols[3] if len(cols) > 3 else '', p.name)
    return casos, origem


def citado(raiz, cid):
    return subprocess.run(['grep', '-rq', cid, str(raiz)], capture_output=True).returncode == 0


def main():
    casos, origem = planos()
    mapa = {}
    for cid, (titulo, tipo, plano) in casos.items():
        if '~~' in titulo:
            mapa[cid] = ('cancelado', '')
            continue
        onde = [nome for nome, raiz in ONDE if raiz.exists() and citado(raiz, cid)]
        if cid in origem:
            onde.insert(0, 'firebase:' + ','.join(origem[cid]))
        mapa[cid] = ('verificado' if onde else 'a verificar', ' + '.join(onde))

    contagem = collections.Counter(v[0] for v in mapa.values())
    total = len(mapa)
    print('═══ Cobertura da migração ═══')
    for k in ('verificado', 'a verificar', 'cancelado'):
        print(f'  {k:12} {contagem[k]:4}  ({contagem[k] * 100 // total}%)')
    print(f'  {"total":12} {total:4}')

    por_plano = collections.defaultdict(lambda: [0, 0])
    for cid, (estado, _) in mapa.items():
        plano = casos[cid][2].split('-plano')[0]
        por_plano[plano][0 if estado == 'verificado' else 1] += 1
    print('\n  por story:')
    for plano in sorted(por_plano):
        ok, falta = por_plano[plano]
        marca = '✅' if falta == 0 else ('🟡' if ok else '🔴')
        print(f'   {marca} {plano:8} {ok:3}/{ok + falta}')

    if len(sys.argv) > 2 and sys.argv[1] == '--lista':
        print()
        for cid in sorted(mapa):
            if mapa[cid][0] == sys.argv[2]:
                print(f'{cid}\t{casos[cid][1]}\t{casos[cid][0]}')


if __name__ == '__main__':
    main()
