#!/usr/bin/env python3
"""Carregador de configuracao compartilhado pelas ferramentas do protocolo.

Le `dossie_modules/_protocolo/projetos.json` e expoe o perfil de um projeto
com valores padrao, para que as ferramentas nao precisem know nada sobre
nenhum projeto especifico.

Uso:
    import _cfg
    cfg = _cfg.load('portal-municipal')
    cfg['dos_dir']      # caminho absoluto do diretorio de dossie
    cfg['raizes']       # {'v5': abs, 'v6': abs}
    cfg['prefixos']     # ['v5', 'v6']
    cfg['modulos']      # {...}
"""
import json
import os
import sys

AQUI = os.path.dirname(os.path.abspath(__file__))          # _tools
DOSSIES_DIR = os.path.dirname(AQUI)                        # dossie_modules
PROTOCOLO_DIR = os.path.join(DOSSIES_DIR, '_protocolo')
WORKSPACE = os.path.dirname(DOSSIES_DIR)                   # .../v7
CONFIG_PATH = os.path.join(PROTOCOLO_DIR, 'projetos.json')

ARQUIVOS_CANONICOS = [
    '00-RESUMO.md',
    '01-ARQUITETURA.md',
    '02-MODELAGEM.md',
    '03-ROTAS-E-CONTROLADORES.md',
    '04-VIEWS-E-UX.md',
    '05-REGRAS-E-PORTABILIDADE.md',
    '06-MIGRACAO-MODERNA.md',
    '07-TESTES.md',
    '08-GAPS-E-DIVIDAS.md',
]

DEFAULT = {
    'titulo': 'Dossiê de Módulos',
    'descricao': '',
    'dos': 'dossie_modules',
    'versoes': {},
    'prefixos_codigo': [],
    'modulos': {'modelo': 'implicito', 'ignorar': []},
    'raiz_codigo': None,
    'alias': {},
    'extras': {},
    'arquivos_canonicos': ARQUIVOS_CANONICOS,
    'min_linhas': 100,
    'max_linhas': 400,
    'extensoes': ['php', 'blade', 'sql', 'json', 'md', 'env', 'yml', 'js'],
}


def _raiz():
    """Raiz do workspace: sobe ate achar o diretorio que contem dossie_modules
    ou, na falta, o proprio pai do diretorio do protocolo."""
    if os.path.isdir(os.path.join(WORKSPACE, 'dossie_modules')):
        return WORKSPACE
    return WORKSPACE


def carregar_config():
    if not os.path.exists(CONFIG_PATH):
        raise SystemExit(f'config nao encontrado: {CONFIG_PATH}')
    with open(CONFIG_PATH, encoding='utf-8') as fh:
        return json.load(fh)


def listar_projetos(cfg=None):
    cfg = cfg or carregar_config()
    return sorted(cfg.get('projetos', {}).keys())


def load(projeto=None, raiz=None):
    """Devolve o perfil do projeto, com defaults preenchidos."""
    cfg = carregar_config()
    projetos = cfg.get('projetos', {})
    if not projeto:
        projeto = cfg.get('padrao')
    if projeto not in projetos:
        raise SystemExit(
            f"projeto desconhecido: {projeto!r}\n"
            f"disponiveis: {', '.join(sorted(projetos))}")
    p = dict(DEFAULT)
    p.update(projetos[projeto])
    p['id'] = projeto
    p['raiz_workspace'] = raiz or _raiz()
    p['raiz_codigo'] = os.path.abspath(os.path.join(
        p['raiz_workspace'], p.get('raiz_codigo') or '.'))
    p['dos_dir'] = os.path.join(p['raiz_workspace'], p['dos'])
    p['raizes'] = {nome: os.path.join(p['raiz_workspace'], v.get('raiz', ''))
                   for nome, v in (p.get('versoes') or {}).items()}
    p['prefixos'] = list(p.get('prefixos_codigo') or [])
    if not p['prefixos']:
        p['prefixos'] = [os.path.basename(r) for r in p['raizes'].values()]
    p['arquivos_canonicos'] = list(p.get('arquivos_canonicos') or ARQUIVOS_CANONICOS)
    return p


def caminho_relativo(path, raiz=None):
    raiz = raiz or _raiz()
    try:
        return os.path.relpath(path, raiz)
    except ValueError:
        return path


def cli_projeto(parser):
    """Adiciona --projeto ao argparse de uma ferramenta."""
    parser.add_argument(
        '--projeto', default=None,
        help='id do projeto em _protocolo/projetos.json (padrao: o marcado como "padrao")')
    parser.add_argument(
        '--raiz', default=None,
        help='raiz do workspace (padrao: deduzida)')
    return parser


def die(msg, code=1):
    print(f'ERRO: {msg}', file=sys.stderr)
    raise SystemExit(code)
