"""Configuração do DNS Shield ISP lida de /etc/dnsshield/config.ini."""
from __future__ import annotations

import configparser
import os
import secrets
import shutil
from dataclasses import dataclass, field
from pathlib import Path

APP_VERSION = "1.3.4"

CONFIG_PATH = Path(os.environ.get("DNSSHIELD_CONFIG", "/etc/dnsshield/config.ini"))
DEFAULT_DB = "/var/lib/dnsshield/dnsshield.db"


def _resolve_bind_bin(nome: str, fallback: str) -> str:
    """Procura o utilitário BIND em PATH e nos caminhos comuns do Debian."""
    caminho = shutil.which(nome)
    if caminho and Path(caminho).exists():
        return caminho
    for d in ("/usr/bin", "/usr/sbin", "/bin", "/sbin"):
        p = Path(d) / nome
        if p.exists():
            return str(p)
    return fallback


@dataclass
class Config:
    db_path: str = DEFAULT_DB
    secret_key: str = field(default_factory=lambda: secrets.token_hex(32))
    server_role: str = "primary"           # primary | secondary
    rpz_zone: str = "bloqueados.fndns.lan"
    rpz_file: str = "/etc/bind/rpz/db.bloqueados"
    sinkhole_ip: str = "127.0.0.1"
    sinkhole_ipv6: str = "::1"
    sinkhole_root: str = "/var/www/dnsshield"
    rndc_bin: str = field(default_factory=lambda: _resolve_bind_bin("rndc", "/usr/sbin/rndc"))
    named_checkzone_bin: str = field(default_factory=lambda: _resolve_bind_bin("named-checkzone", "/usr/sbin/named-checkzone"))
    bind_service: str = "bind9"
    panel_service: str = "dnsshield"
    install_dir: str = "/opt/dnsshield"
    github_repo: str = "juniorgnv-svg/secure-dns-guardian"
    licenca_url: str = "https://licenca.jbinfo.com.br"
    peer_ip: str = ""


_cached: Config | None = None


def get_config(reload: bool = False) -> Config:
    global _cached
    if _cached is not None and not reload:
        return _cached

    cfg = Config()
    if CONFIG_PATH.exists():
        parser = configparser.ConfigParser()
        parser.read(CONFIG_PATH)
        for section in parser.sections():
            for key, value in parser.items(section):
                if hasattr(cfg, key) and value != "":
                    setattr(cfg, key, value)

    # Se o config.ini aponta para um binário que não existe, resolve novamente.
    cfg.rndc_bin = _resolve_bind_bin(Path(cfg.rndc_bin).name, cfg.rndc_bin)
    cfg.named_checkzone_bin = _resolve_bind_bin(Path(cfg.named_checkzone_bin).name, cfg.named_checkzone_bin)

    env_db = os.environ.get("DNSSHIELD_DB")
    if env_db:
        cfg.db_path = env_db

    _cached = cfg
    return cfg

