"""
Send SystemLog reads/writes through the "logs" database alias — a second
connection to the same database (see settings.DATABASES). Its writes commit
on their own, so a log entry about a failure survives even when the
transaction it happened in is rolled back.

Under the test runner (which mirrors "logs" onto "default" anyway) the
default connection is used, so tests don't have to opt in to a second
database.
"""

from django.core import mail

LOGS_DB = "logs"
APP_LABEL = "system_logs"


def _alias() -> str:
    # setup_test_environment() installs mail.outbox; it never exists otherwise.
    return "default" if hasattr(mail, "outbox") else LOGS_DB


class SystemLogRouter:
    def db_for_read(self, model, **hints):
        return _alias() if model._meta.app_label == APP_LABEL else None

    def db_for_write(self, model, **hints):
        return _alias() if model._meta.app_label == APP_LABEL else None

    def allow_relation(self, obj1, obj2, **hints):
        # Both aliases point at the same database, so FKs (e.g. to User) are fine.
        if APP_LABEL in (obj1._meta.app_label, obj2._meta.app_label):
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # Tables live in the one real database, migrated via "default".
        if db == LOGS_DB:
            return False
        return None
