"""
Package dei reader — lettura dati da diversi formati.

Contiene la ReaderFactory per creare automaticamente il reader
corretto in base all'estensione del file.

Uso::

    from dataprofiler.readers import ReaderFactory

    reader = ReaderFactory.create("dati.csv")
    dati = reader.read()
"""

import os

from .base import BaseReader
from .csv_reader import CsvReader
from .excel_reader import ExcelReader
from .json_reader import JsonReader
from dataprofiler.exceptions import UnsupportedFormatError


class ReaderFactory:
    """Factory per creare il reader appropriato in base all'estensione.

    Implementa il pattern Factory Method: il codice chiamante non ha
    bisogno di sapere quale reader concreto verrà utilizzato.

    Il registro interno mappa estensioni → classi reader e può essere
    esteso dinamicamente con il metodo register().

    Esempio::

        reader = ReaderFactory.create("dati.csv")             # → CsvReader
        reader = ReaderFactory.create("vendite.xlsx")          # → ExcelReader
        reader = ReaderFactory.create("prodotti.json")         # → JsonReader

        # Aggiungere supporto per un nuovo formato
        ReaderFactory.register(".tsv", CsvReader)
    """

    _registry: dict[str, type[BaseReader]] = {
        ".csv": CsvReader,
        ".xlsx": ExcelReader,
        ".xls": ExcelReader,
        ".json": JsonReader,
    }

    @classmethod
    def create(cls, filepath: str, **kwargs) -> BaseReader:
        """Crea un reader basato sull'estensione del file.

        Args:
            filepath: Percorso del file da leggere.
            **kwargs: Parametri aggiuntivi passati al costruttore del reader.

        Returns:
            Un'istanza del reader appropriato.

        Raises:
            UnsupportedFormatError: Se l'estensione non è supportata.
        """
        _, ext = os.path.splitext(filepath)
        ext = ext.lower()

        reader_class = cls._registry.get(ext)
        if reader_class is None:
            supported = ", ".join(sorted(cls._registry.keys()))
            raise UnsupportedFormatError(
                f"Formato '{ext}' non supportato. Formati validi: {supported}"
            )
        return reader_class(filepath, **kwargs)

    @classmethod
    def register(cls, extension: str, reader_class: type[BaseReader]) -> None:
        """Registra un nuovo reader per un'estensione.

        Permette di estendere il package con reader personalizzati
        senza modificare il codice esistente (Open/Closed Principle).

        Args:
            extension: Estensione del file (es. ".tsv").
            reader_class: Classe reader da associare.
        """
        if not extension.startswith("."):
            extension = f".{extension}"
        cls._registry[extension] = reader_class

    @classmethod
    def supported_formats(cls) -> list[str]:
        """Restituisce la lista dei formati supportati.

        Returns:
            Lista di estensioni supportate.
        """
        return sorted(cls._registry.keys())


__all__ = [
    "BaseReader",
    "CsvReader",
    "ExcelReader",
    "JsonReader",
    "ReaderFactory",
]
