"""gvsdsdk.db_router — 开箱即用的 SAAS 数据库路由器

子服务器只需在 settings.py 中配置：
    DATABASE_ROUTERS = ['gvsdsdk.db_router.SAASDatabaseRouter']

即可自动将 gvsdsdk 的所有模型路由到 SAAS 主库。

配置项（settings.py）：
    GVSDSDK_SAAS_DB_ALIAS = 'saas'       # SAAS 数据库别名，默认 'saas'
    GVSDSDK_SAAS_READ_ONLY = True         # 子服务器是否只读，默认 True
"""


class SAASDatabaseRouter:
    """SAAS 模型数据库路由器——将 gvsdsdk 模型路由到 SAAS 主库

    用法：
        # settings.py
        DATABASES = {
            'default': { ... },           # 本地数据库
            'saas': {                     # SAAS 主库
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'Users',
                ...
            },
        }
        DATABASE_ROUTERS = ['gvsdsdk.db_router.SAASDatabaseRouter']

        # 可选配置
        GVSDSDK_SAAS_DB_ALIAS = 'saas'    # 默认 'saas'
        GVSDSDK_SAAS_READ_ONLY = True     # 默认 True（子服务器只读）
    """

    # gvsdsdk 内所有模块前缀
    _GVSDSDK_MODULES = frozenset({
        'gvsdsdk.models',
        'gvsdsdk.commission.models',
        'gvsdsdk.payment.models',
    })

    # gvsdsdk 内所有 app_label
    _GVSDSDK_APP_LABELS = frozenset({
        'gvsdsdk',
    })

    def _get_saas_db(self):
        from django.conf import settings
        return getattr(settings, 'GVSDSDK_SAAS_DB_ALIAS', 'saas')

    def _is_read_only(self):
        from django.conf import settings
        return getattr(settings, 'GVSDSDK_SAAS_READ_ONLY', True)

    def _is_gvsdsdk_model(self, model):
        """判断模型是否属于 gvsdsdk"""
        # 按模块路径判断
        module = getattr(model, '__module__', '')
        if module in self._GVSDSDK_MODULES or module.startswith('gvsdsdk.'):
            return True
        # 按 app_label 判断
        app_label = getattr(model._meta, 'app_label', '')
        if app_label in self._GVSDSDK_APP_LABELS:
            return True
        return False

    def db_for_read(self, model, **hints):
        if self._is_gvsdsdk_model(model):
            return self._get_saas_db()
        return None

    def db_for_write(self, model, **hints):
        if self._is_gvsdsdk_model(model):
            if self._is_read_only():
                raise RuntimeError(
                    "gvsdsdk SAAS database is read-only for sub-servers. "
                    "Set GVSDSDK_SAAS_READ_ONLY=False to allow writes."
                )
            return self._get_saas_db()
        return None

    def allow_relation(self, obj1, obj2, **hints):
        # 允许同一数据库内的关联
        db1 = self.db_for_read(obj1.__class__)
        db2 = self.db_for_read(obj2.__class__)
        if db1 and db2 and db1 == db2:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # gvsdsdk 模型不迁移（managed=False 或由主服务器管理）
        if app_label in self._GVSDSDK_APP_LABELS:
            return db != self._get_saas_db()
        return None
