"""Tests for config:get — SDK + CLI."""

from __future__ import annotations

import pytest
from click.testing import CliRunner

from kuberoku.cli.main import cli
from kuberoku.exceptions import AppNotFoundError, ConfigVarNotFoundError
from kuberoku.factory import KuberokuFactory
from kuberoku.sdk.config import ConfigService


class TestConfigGetSDK:
    """SDK-level tests for ConfigService.get()."""

    def test_get_from_configmap(self, config_service: ConfigService, app_name: str) -> None:
        config_service.set(app_name, {"DATABASE_URL": "postgres://localhost/db"})
        value, source = config_service.get(app_name, "DATABASE_URL")
        assert value == "postgres://localhost/db"
        assert source == "configmap"

    def test_get_from_secret(self, config_service: ConfigService, app_name: str) -> None:
        config_service.set(app_name, {"API_KEY": "secret123"}, secret=True)
        value, source = config_service.get(app_name, "API_KEY")
        assert value == "secret123"
        assert source == "secret"

    def test_get_key_not_found(self, config_service: ConfigService, app_name: str) -> None:
        with pytest.raises(ConfigVarNotFoundError, match="MISSING"):
            config_service.get(app_name, "MISSING")

    def test_get_app_not_found(self, config_service: ConfigService) -> None:
        with pytest.raises(AppNotFoundError, match="nonexistent"):
            config_service.get("nonexistent", "KEY")

    def test_get_secret_overrides_configmap(
        self, config_service: ConfigService, app_name: str
    ) -> None:
        """If same key exists in both CM and Secret, Secret wins."""
        config_service.set(app_name, {"KEY": "cm_value"})
        config_service.set(app_name, {"KEY": "secret_value"}, secret=True)
        value, source = config_service.get(app_name, "KEY")
        assert value == "secret_value"
        assert source == "secret"


class TestConfigGetCLI:
    """CLI-level tests for config:get."""

    def test_get_cli(self, cli_runner: CliRunner, factory: KuberokuFactory) -> None:
        factory.apps.create("myapp")
        factory.config.set("myapp", {"KEY": "value"})
        result = cli_runner.invoke(
            cli, ["config:get", "KEY", "--app", "myapp"], obj={"factory": factory}
        )
        assert result.exit_code == 0
        assert "value" in result.output

    def test_get_cli_secret_masked(self, cli_runner: CliRunner, factory: KuberokuFactory) -> None:
        factory.apps.create("myapp")
        factory.config.set("myapp", {"TOKEN": "supersecret"}, secret=True)
        result = cli_runner.invoke(
            cli, ["config:get", "TOKEN", "--app", "myapp"], obj={"factory": factory}
        )
        assert result.exit_code == 0
        assert "supersecret" not in result.output
        assert "********" in result.output

    def test_get_cli_reveal(self, cli_runner: CliRunner, factory: KuberokuFactory) -> None:
        factory.apps.create("myapp")
        factory.config.set("myapp", {"TOKEN": "supersecret"}, secret=True)
        result = cli_runner.invoke(
            cli,
            ["config:get", "TOKEN", "--reveal", "--app", "myapp"],
            obj={"factory": factory},
        )
        assert result.exit_code == 0
        assert "supersecret" in result.output

    def test_get_cli_not_found(self, cli_runner: CliRunner, factory: KuberokuFactory) -> None:
        factory.apps.create("myapp")
        result = cli_runner.invoke(
            cli, ["config:get", "MISSING", "--app", "myapp"], obj={"factory": factory}
        )
        assert result.exit_code != 0

    def test_get_cli_space_syntax(self, cli_runner: CliRunner, factory: KuberokuFactory) -> None:
        """'config get KEY' works same as 'config:get KEY'."""
        factory.apps.create("myapp")
        factory.config.set("myapp", {"KEY": "value"})
        result = cli_runner.invoke(
            cli, ["config", "get", "KEY", "--app", "myapp"], obj={"factory": factory}
        )
        assert result.exit_code == 0
        assert "value" in result.output

    def test_get_cli_reveal_configmap_only(
        self, cli_runner: CliRunner, factory: KuberokuFactory
    ) -> None:
        """--reveal on a ConfigMap var shows the value (no masking)."""
        factory.apps.create("myapp")
        factory.config.set("myapp", {"PUBLIC": "plaintext"})
        result = cli_runner.invoke(
            cli,
            ["config:get", "PUBLIC", "--reveal", "--app", "myapp"],
            obj={"factory": factory},
        )
        assert result.exit_code == 0
        assert "plaintext" in result.output
