# scanner.py
# Funções para ler diretórios e listar ficheiros
from pathlib import Path
from tqdm import tqdm
from modules.utils import gerar_assinatura_SHA256_ficheiro
from modules.logger import logger


def listar_ficheiros(
    origem: str = ".",
    incluir_ocultos: bool = True,
    extensoes: list[str] | None = None,
) -> list:
    """
    Percorrer recursivamente a pasta de origem e devolver lista de caminhos
    completos dos ficheiros.
    versão Pathlib
    """
    caminho_origem = Path(origem)
    if not caminho_origem.exists():
        logger.error("A pasta de origem '%s' não existe.", origem)
        raise FileNotFoundError(f"Erro: a pasta '{origem}' não existe.")
    if not caminho_origem.is_dir():
        logger.error("O caminho '%s' não é um directório.", origem)
        raise NotADirectoryError(f"Erro: o caminho '{origem}' não é um directório.")
    # se for passado filtro de extensoes, processar lista de extensoes para
    # que cada extensão tenha o formato '.xxx'
    if extensoes:
        extensoes = [
            ext.lower() if ext.startswith(".") else f".{ext.lower()}"
            for ext in extensoes
        ]
    # criar lista de ficheiros
    ficheiros = []
    itens = caminho_origem.rglob("*")

    with tqdm(desc="A listar ficheiros", unit=" ficheiro") as barra_progresso:
        for item in itens:
            if item.is_file():
                if not incluir_ocultos and item.name.startswith("."):
                    continue
                if extensoes and item.suffix.lower() not in extensoes:
                    continue
                ficheiros.append(str(item))
            barra_progresso.update(1)

    return ficheiros


def listar_ficheiros_unicos(
    origem: str = ".",
    incluir_ocultos: bool = True,
    extensoes: list[str] | None = None,
) -> dict[str, list[str]]:
    """
    Listar ficheiros unicos na pasta origem, agrupando caminhos por assinatura
    SHA256.
    Retorna dicionario: { assinatura: [caminho1, caminho2, ...] }
    """
    caminho_origem = Path(origem)
    if not caminho_origem.exists():
        logger.error("A pasta de origem '%s' não existe.", origem)
        raise FileNotFoundError(f"Erro: a pasta '{origem}' não existe.")
    if not caminho_origem.is_dir():
        logger.error("O caminho '%s' não é um directório.", origem)
        raise NotADirectoryError(f"Erro: o caminho '{origem}' não é um directório.")
    # se for passado filtro de extensoes, processar lista de extensoes para
    # que cada extensão tenha o formato '.xxx'
    if extensoes:
        extensoes = [
            ext.lower() if ext.startswith(".") else f".{ext.lower()}"
            for ext in extensoes
        ]

    # dicionario de ficheiros com assinatura
    ficheiros_por_assinatura: dict[str, list[str]] = {}
    itens = caminho_origem.rglob("*")

    with tqdm(desc="A listar ficheiros", unit=" ficheiro") as barra_progresso:
        for item in itens:
            if item.is_file():
                if not incluir_ocultos and item.name.startswith("."):
                    continue
                if extensoes and item.suffix.lower() not in extensoes:
                    continue
                assinatura = gerar_assinatura_SHA256_ficheiro(str(item))
                ficheiros_por_assinatura.setdefault(assinatura, []).append(str(item))
            barra_progresso.update(1)

    return ficheiros_por_assinatura
