"""Tests for the AddonDef registry and built-in types."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest

from kuberoku.addons import ADDON_REGISTRY, AddonDef, _discover_addon_plugins, get_addon_def
from kuberoku.addons.postgres import POSTGRES
from kuberoku.addons.redis import REDIS
from kuberoku.exceptions import AddonTypeNotSupportedError


def test_registry_has_postgres() -> None:
    assert "postgres" in ADDON_REGISTRY


def test_registry_has_redis() -> None:
    assert "redis" in ADDON_REGISTRY


def test_get_addon_def_postgres() -> None:
    defn = get_addon_def("postgres")
    assert isinstance(defn, AddonDef)
    assert defn.type_name == "postgres"
    assert defn.port == 5432


def test_get_addon_def_redis() -> None:
    defn = get_addon_def("redis")
    assert defn.type_name == "redis"
    assert defn.port == 6379


def test_get_addon_def_unknown() -> None:
    with pytest.raises(AddonTypeNotSupportedError, match="mongodb"):
        get_addon_def("mongodb")


def test_postgres_fields() -> None:
    assert POSTGRES.image == "postgres:16"
    assert POSTGRES.needs_storage is True
    assert POSTGRES.storage_optional is False
    assert POSTGRES.needs_auth is True
    assert POSTGRES.env_key == "DATABASE_URL"
    assert POSTGRES.exec_command is not None
    assert POSTGRES.backup_command is not None


def test_redis_fields() -> None:
    assert REDIS.image == "redis:7"
    assert REDIS.needs_storage is True
    assert REDIS.storage_optional is True
    assert REDIS.env_key == "REDIS_URL"
    assert REDIS.backup_command is None


def test_postgres_readiness_probe() -> None:
    probe = POSTGRES.readiness_probe
    assert "exec" in probe
    assert "pg_isready" in probe["exec"]["command"]


def test_redis_readiness_probe() -> None:
    probe = REDIS.readiness_probe
    assert "exec" in probe
    assert "redis-cli" in probe["exec"]["command"]


def test_postgres_env_builder() -> None:
    assert POSTGRES.container_env_builder is not None
    env = POSTGRES.container_env_builder("my-secret", "user", "pass", "db")
    env_names = [e["name"] for e in env]
    assert "POSTGRES_USER" in env_names
    assert "POSTGRES_PASSWORD" in env_names
    assert "POSTGRES_DB" in env_names
    assert "PGDATA" in env_names


def test_redis_env_builder() -> None:
    assert REDIS.container_env_builder is not None
    env = REDIS.container_env_builder("my-secret", "", "pass", "")
    env_names = [e["name"] for e in env]
    assert "REDIS_PASSWORD" in env_names


class TestAddonPluginDiscovery:
    """Tests for _discover_addon_plugins() error handling."""

    def test_plugin_load_failure_warns(self) -> None:
        """A plugin that fails to load emits a warning but doesn't crash."""
        bad_ep = MagicMock()
        bad_ep.name = "badplugin"
        bad_ep.load.side_effect = ImportError("broken")

        with (
            patch(
                "kuberoku.addons.importlib.metadata.entry_points",
                return_value=[bad_ep],
            ),
            pytest.warns(UserWarning, match="Failed to load addon plugin 'badplugin'"),
        ):
            _discover_addon_plugins()

    def test_builtin_conflict_warns(self) -> None:
        """A plugin with a built-in name emits a warning and is skipped."""
        conflict_ep = MagicMock()
        conflict_ep.name = "postgres"  # conflicts with built-in

        with (
            patch(
                "kuberoku.addons.importlib.metadata.entry_points",
                return_value=[conflict_ep],
            ),
            pytest.warns(UserWarning, match="conflicts with built-in"),
        ):
            _discover_addon_plugins()
