import keyword
import re
from typing import Type
from sqlalchemy.engine import Engine

from ._model_registry import get_global_registry, apps_label


class SqlAlchemyModelBuilder:
    """
    Builds a single SQLAlchemy ORM model from a specific database table.
    Delegates to the process-wide ModelRegistry for thread-safety and caching.
    """

    def __init__(self, engine: Engine, table_name: str):
        self.engine = engine
        self.table_name = table_name

    def build_model(self) -> Type:
        """Reflects the table and returns the mapped ORM class."""
        registry = get_global_registry()

        # The registry handles locking internally, so we don't need a lock here
        return registry.get_model(
            engine=self.engine,
            table_name=self.table_name,
            module_label=apps_label,
            prefer_stable_names=True,
        )

    @staticmethod
    def _normalize_class_name(table_name: str) -> str:
        return "".join(word.capitalize() for word in table_name.split("_"))

    @staticmethod
    def _normalize_column_name(column_name: str) -> str:
        # Useful helper if you ever need to generate column aliases
        sane_name = re.sub(r"\W", "_", column_name)
        sane_name = re.sub(r"^\d", r"_\g<0>", sane_name)
        if keyword.iskeyword(sane_name):
            return f"{sane_name}_field"
        return sane_name
