from django.conf import settings

DEFAULTS = {
    "BROKERS": {
        "default": {
            "ENGINE": "django_devicehub.brokers.mqtt.MQTTBroker",
            "HOST": "localhost",
            "PORT": 1883,
            "USERNAME": "",
            "PASSWORD": "",
            "CLIENT_ID": "",
            "KEEPALIVE": 60,
            "USE_TLS": False,
            "CA_CERTS": "",
            "CERTFILE": "",
            "KEYFILE": "",
            "USE_SHARED_SUBSCRIPTIONS": True,
            "SHARE_GROUP": "django-devicehub",
            "AUTH_BACKEND": False,
        }
    },
    "STORAGE": {
        "ENGINE": "django_devicehub.storage.django_orm.DjangoORMStorage",
    },
    "TOPIC_PREFIX": "things",
    "AUTO_API": True,
    "AUTO_ADMIN": True,
    "DEVICE_ID_MAX_LENGTH": 128,
    "API_KEY_LENGTH": 64,
    "HEARTBEAT_TIMEOUT_MULTIPLIER": 2.5,
}


class DevicehubSettings:
    def __init__(self):
        self._cached = None

    def _get_settings(self):
        if self._cached is None:
            user_settings = getattr(settings, "DJANGO_DEVICEHUB", {})
            self._cached = self._merge(DEFAULTS, user_settings)
        return self._cached

    def _merge(self, defaults, overrides):
        result = {}
        for key, default_value in defaults.items():
            if key in overrides:
                override = overrides[key]
                if isinstance(default_value, dict) and isinstance(override, dict):
                    result[key] = self._merge(default_value, override)
                else:
                    result[key] = override
            else:
                result[key] = default_value
        # Include keys from overrides not in defaults
        for key in overrides:
            if key not in defaults:
                result[key] = overrides[key]
        return result

    def __getattr__(self, name):
        s = self._get_settings()
        if name in s:
            return s[name]
        raise AttributeError(f"Invalid django-devicehub setting: {name}")

    def invalidate_cache(self):
        self._cached = None


devicehub_settings = DevicehubSettings()
