"""Tests for ``ilum.cli.defaults.resolve_profile_defaults``."""

from __future__ import annotations

from unittest.mock import patch

from ilum.cli.defaults import resolve_access_type, resolve_profile_defaults
from ilum.config.manager import ConfigManager
from ilum.config.models import ClusterConfig, IlumConfig, ProfileConfig
from ilum.constants import DEFAULT_ACCESS_TYPE, DEFAULT_NAMESPACE, DEFAULT_RELEASE_NAME


class TestResolveProfileDefaults:
    def test_all_provided(self) -> None:
        """Explicit values pass through unchanged — no config I/O."""
        r, n, c = resolve_profile_defaults("my-rel", "my-ns", "my-ctx")
        assert r == "my-rel"
        assert n == "my-ns"
        assert c == "my-ctx"

    def test_none_values_resolved_from_profile(self, tmp_config_dir) -> None:
        """Values are pulled from the active profile when not provided."""
        cfg = IlumConfig(
            active_profile="dev",
            profiles={
                "dev": ProfileConfig(
                    name="dev",
                    release_name="ilum-dev",
                    cluster=ClusterConfig(
                        kubecontext="kind-dev",
                        namespace="ilum-ns",
                    ),
                ),
            },
        )
        ConfigManager(tmp_config_dir).save(cfg)

        r, n, c = resolve_profile_defaults(None, None, None)

        assert r == "ilum-dev"
        assert n == "ilum-ns"
        assert c == "kind-dev"

    def test_no_config_falls_back_to_constants(self, tmp_config_dir) -> None:
        """When no config file exists, hardcoded defaults are returned."""
        r, n, c = resolve_profile_defaults(None, None, None)

        assert r == DEFAULT_RELEASE_NAME
        assert n == DEFAULT_NAMESPACE
        assert c == ""

    def test_empty_profile_fields_fall_back(self, tmp_config_dir) -> None:
        """Profile exists but release_name is empty → constants."""
        cfg = IlumConfig(
            active_profile="default",
            profiles={
                "default": ProfileConfig(name="default"),
            },
        )
        ConfigManager(tmp_config_dir).save(cfg)

        r, n, c = resolve_profile_defaults(None, None, None)

        assert r == DEFAULT_RELEASE_NAME
        assert n == DEFAULT_NAMESPACE
        assert c == ""

    def test_partial_override(self, tmp_config_dir) -> None:
        """Explicit release + None namespace resolves namespace from profile."""
        cfg = IlumConfig(
            active_profile="prod",
            profiles={
                "prod": ProfileConfig(
                    name="prod",
                    release_name="ilum-prod",
                    cluster=ClusterConfig(
                        kubecontext="eks-prod",
                        namespace="production",
                    ),
                ),
            },
        )
        ConfigManager(tmp_config_dir).save(cfg)

        r, n, c = resolve_profile_defaults("explicit", None, None)

        assert r == "explicit"
        assert n == "production"
        assert c == "eks-prod"

    def test_config_load_error_falls_back(self) -> None:
        """If config loading throws, fall back to constants gracefully."""
        with patch(
            "ilum.config.paths.IlumPaths.default",
            side_effect=RuntimeError("corrupt"),
        ):
            r, n, c = resolve_profile_defaults(None, None, None)

        assert r == DEFAULT_RELEASE_NAME
        assert n == DEFAULT_NAMESPACE
        assert c == ""


class TestResolveAccessType:
    def test_from_flag(self) -> None:
        """Explicit CLI flag is returned as-is."""
        assert resolve_access_type("port-forward") == "port-forward"

    def test_from_profile(self, tmp_config_dir) -> None:
        """access_type is pulled from the active profile."""
        cfg = IlumConfig(
            active_profile="dev",
            profiles={
                "dev": ProfileConfig(name="dev", access_type="ingress"),
            },
        )
        ConfigManager(tmp_config_dir).save(cfg)

        assert resolve_access_type(None) == "ingress"

    def test_default(self, tmp_config_dir) -> None:
        """Falls back to DEFAULT_ACCESS_TYPE when no config."""
        assert resolve_access_type(None) == DEFAULT_ACCESS_TYPE

    def test_profile_default_access_type(self) -> None:
        """ProfileConfig.access_type defaults to 'nodeport'."""
        p = ProfileConfig(name="test")
        assert p.access_type == "nodeport"
