"""Tests for the deployment preset data model and registry."""

from __future__ import annotations

import pytest

from ilum.core.modules import ModuleResolver
from ilum.core.presets import (
    PRESETS,
    DeploymentPreset,
    get_preset,
    list_presets,
)


class TestDeploymentPresetDataclass:
    def test_preset_is_frozen(self) -> None:
        preset = DeploymentPreset(
            name="test",
            description="A test preset",
            modules=("core",),
        )
        with pytest.raises(AttributeError):
            preset.name = "changed"  # type: ignore[misc]


class TestDevelopmentPreset:
    def test_development_preset_modules(self) -> None:
        preset = PRESETS["development"]
        expected = (
            "core",
            "ui",
            "mongodb",
            "postgresql",
            "minio",
            "jupyter",
            "gitea",
            "openldap",
        )
        assert preset.modules == expected
        assert preset.set_flags == ()
        assert preset.requires_input == ()


class TestProductionPreset:
    def test_production_preset_modules(self) -> None:
        preset = PRESETS["production"]
        expected = (
            "core",
            "ui",
            "mongodb",
            "postgresql",
            "minio",
            "jupyter",
            "gitea",
            "monitoring",
            "loki",
            "openldap",
        )
        assert preset.modules == expected
        assert "global.security.enabled=true" in preset.set_flags
        assert "ilum-core.replicaCount=2" in preset.set_flags
        assert preset.requires_input == ()


class TestDataEngineeringPreset:
    def test_data_engineering_preset_modules(self) -> None:
        preset = PRESETS["data-engineering"]
        expected = (
            "core",
            "ui",
            "mongodb",
            "postgresql",
            "minio",
            "jupyter",
            "gitea",
            "sql",
            "airflow",
            "superset",
            "trino",
            "hive-metastore",
            "openldap",
        )
        assert preset.modules == expected
        assert preset.set_flags == ()
        assert preset.requires_input == ()


class TestAirGappedPreset:
    def test_air_gapped_preset(self) -> None:
        preset = PRESETS["air-gapped"]
        expected_modules = ("core", "ui", "mongodb", "postgresql", "minio", "jupyter", "gitea")
        assert preset.modules == expected_modules
        assert "global.imageRegistry=<REGISTRY>" in preset.set_flags
        assert "global.imageRegistry" in preset.requires_input


class TestListPresets:
    def test_list_presets_returns_all(self) -> None:
        presets = list_presets()
        assert len(presets) == 4
        names = [p.name for p in presets]
        assert names == ["development", "production", "data-engineering", "air-gapped"]


class TestGetPreset:
    def test_get_preset_found(self) -> None:
        preset = get_preset("development")
        assert preset is not None
        assert preset.name == "development"

    def test_get_preset_not_found(self) -> None:
        assert get_preset("nonexistent") is None


class TestPresetModuleValidity:
    def test_all_preset_modules_exist_in_registry(self) -> None:
        resolver = ModuleResolver()
        all_module_names = {m.name for m in resolver.all_modules()}
        for preset in list_presets():
            for module_name in preset.modules:
                assert module_name in all_module_names, (
                    f"Preset '{preset.name}' references unknown module '{module_name}'"
                )
