"""Tests for CLI add command with environment support."""

from unittest.mock import Mock, patch

import pytest
from click.testing import CliRunner

from debrepomanager.cli import cli


@pytest.fixture
def runner():
    """Create CLI test runner."""
    return CliRunner()


@pytest.fixture
def mock_config():
    """Mock config."""
    config = Mock()
    config.publish_base = "/test/repo/public"
    config.auto_create_repos = True
    return config


class TestAddWithEnvironment:
    """Tests for add command with environment option."""

    def test_add_stable_environment(self, runner, mock_config, tmp_path):
        """Test add with stable environment."""
        # Create test package directory
        pkg_dir = tmp_path / "armbian-bookworm"
        pkg_dir.mkdir()
        (pkg_dir / "test.deb").write_text("fake deb")

        with patch("debrepomanager.cli.Config") as mock_config_class:
            mock_config_class.return_value = mock_config

            with patch("debrepomanager.cli.AptlyManager") as mock_aptly_class:
                mock_aptly = Mock()
                mock_aptly.repo_exists.return_value = True
                mock_aptly.add_packages = Mock()
                mock_aptly_class.return_value = mock_aptly

                result = runner.invoke(
                    cli,
                    [
                        "add",
                        "--environment",
                        "stable",
                        "--codename",
                        "bookworm",
                        "--package-dir",
                        str(pkg_dir),
                    ],
                )

                assert result.exit_code == 0
                # Component should be auto-generated
                mock_aptly.add_packages.assert_called_once()
                args = mock_aptly.add_packages.call_args
                assert args[0][0] == "bookworm"
                assert args[0][1] == "jethome-armbian-bookworm"

    def test_add_beta_environment(self, runner, mock_config, tmp_path):
        """Test add with beta environment."""
        pkg_dir = tmp_path / "test-packages"
        pkg_dir.mkdir()
        (pkg_dir / "test.deb").write_text("fake deb")

        with patch("debrepomanager.cli.Config") as mock_config_class:
            mock_config_class.return_value = mock_config

            with patch("debrepomanager.cli.AptlyManager") as mock_aptly_class:
                mock_aptly = Mock()
                mock_aptly.repo_exists.return_value = True
                mock_aptly.add_packages = Mock()
                mock_aptly_class.return_value = mock_aptly

                with patch("os.environ", {}):
                    result = runner.invoke(
                        cli,
                        [
                            "add",
                            "--environment",
                            "beta",
                            "--codename",
                            "bookworm",
                            "--package-dir",
                            str(pkg_dir),
                        ],
                    )

                    assert result.exit_code == 0
                    # Check that publish_prefix was set
                    import os

                    assert os.environ.get("REPOMANAGER_PUBLISH_PREFIX") == "beta"

    def test_add_test_environment(self, runner, mock_config, tmp_path):
        """Test add with test environment."""
        pkg_dir = tmp_path / "test-packages"
        pkg_dir.mkdir()
        (pkg_dir / "test.deb").write_text("fake deb")

        with patch("debrepomanager.cli.Config") as mock_config_class:
            mock_config_class.return_value = mock_config

            with patch("debrepomanager.cli.AptlyManager") as mock_aptly_class:
                mock_aptly = Mock()
                mock_aptly.repo_exists.return_value = True
                mock_aptly.add_packages = Mock()
                mock_aptly_class.return_value = mock_aptly

                with patch("os.environ", {}):
                    result = runner.invoke(
                        cli,
                        [
                            "add",
                            "--environment",
                            "test",
                            "--codename",
                            "bookworm",
                            "--package-dir",
                            str(pkg_dir),
                        ],
                    )

                    assert result.exit_code == 0
                    import os

                    assert os.environ.get("REPOMANAGER_PUBLISH_PREFIX") == "test"

    def test_add_environment_auto_component(self, runner, mock_config, tmp_path):
        """Test component auto-generation from directory name."""
        pkg_dir = tmp_path / "my-packages"
        pkg_dir.mkdir()
        (pkg_dir / "test.deb").write_text("fake deb")

        with patch("debrepomanager.cli.Config") as mock_config_class:
            mock_config_class.return_value = mock_config

            with patch("debrepomanager.cli.AptlyManager") as mock_aptly_class:
                mock_aptly = Mock()
                mock_aptly.repo_exists.return_value = True
                mock_aptly.add_packages = Mock()
                mock_aptly_class.return_value = mock_aptly

                result = runner.invoke(
                    cli,
                    [
                        "add",
                        "--environment",
                        "stable",
                        "--codename",
                        "bookworm",
                        "--package-dir",
                        str(pkg_dir),
                    ],
                )

                assert result.exit_code == 0
                args = mock_aptly.add_packages.call_args
                # Should add jethome- prefix
                assert args[0][1] == "jethome-my-packages"

    def test_add_environment_jethome_prefix_preserved(
        self, runner, mock_config, tmp_path
    ):
        """Test that jethome- prefix is not duplicated."""
        pkg_dir = tmp_path / "jethome-tools"
        pkg_dir.mkdir()
        (pkg_dir / "test.deb").write_text("fake deb")

        with patch("debrepomanager.cli.Config") as mock_config_class:
            mock_config_class.return_value = mock_config

            with patch("debrepomanager.cli.AptlyManager") as mock_aptly_class:
                mock_aptly = Mock()
                mock_aptly.repo_exists.return_value = True
                mock_aptly.add_packages = Mock()
                mock_aptly_class.return_value = mock_aptly

                result = runner.invoke(
                    cli,
                    [
                        "add",
                        "--environment",
                        "stable",
                        "--codename",
                        "bookworm",
                        "--package-dir",
                        str(pkg_dir),
                    ],
                )

                assert result.exit_code == 0
                args = mock_aptly.add_packages.call_args
                # Should NOT duplicate prefix
                assert args[0][1] == "jethome-tools"

    def test_add_environment_explicit_component(self, runner, mock_config, tmp_path):
        """Test environment with explicit component."""
        pkg_dir = tmp_path / "packages"
        pkg_dir.mkdir()
        (pkg_dir / "test.deb").write_text("fake deb")

        with patch("debrepomanager.cli.Config") as mock_config_class:
            mock_config_class.return_value = mock_config

            with patch("debrepomanager.cli.AptlyManager") as mock_aptly_class:
                mock_aptly = Mock()
                mock_aptly.repo_exists.return_value = True
                mock_aptly.add_packages = Mock()
                mock_aptly_class.return_value = mock_aptly

                result = runner.invoke(
                    cli,
                    [
                        "add",
                        "--environment",
                        "beta",
                        "--codename",
                        "bookworm",
                        "--component",
                        "jethome-custom",
                        "--package-dir",
                        str(pkg_dir),
                    ],
                )

                assert result.exit_code == 0
                args = mock_aptly.add_packages.call_args
                # Should use explicit component
                assert args[0][1] == "jethome-custom"

    def test_add_environment_without_package_dir(self, runner, mock_config, tmp_path):
        """Test error when environment without package-dir and component."""
        # Create a fake package file so click doesn't fail on path validation
        fake_pkg = tmp_path / "test.deb"
        fake_pkg.write_text("fake deb")

        with patch("debrepomanager.cli.Config") as mock_config_class:
            mock_config_class.return_value = mock_config

            result = runner.invoke(
                cli,
                [
                    "add",
                    "--environment",
                    "stable",
                    "--codename",
                    "bookworm",
                    "--packages",
                    str(fake_pkg),
                ],
            )

            assert result.exit_code != 0
            assert "component is required" in result.output.lower()

    def test_add_without_environment(self, runner, mock_config, tmp_path):
        """Test traditional add without environment."""
        pkg_dir = tmp_path / "packages"
        pkg_dir.mkdir()
        (pkg_dir / "test.deb").write_text("fake deb")

        with patch("debrepomanager.cli.Config") as mock_config_class:
            mock_config_class.return_value = mock_config

            with patch("debrepomanager.cli.AptlyManager") as mock_aptly_class:
                mock_aptly = Mock()
                mock_aptly.repo_exists.return_value = True
                mock_aptly.add_packages = Mock()
                mock_aptly_class.return_value = mock_aptly

                result = runner.invoke(
                    cli,
                    [
                        "add",
                        "--codename",
                        "bookworm",
                        "--component",
                        "jethome-tools",
                        "--package-dir",
                        str(pkg_dir),
                    ],
                )

                assert result.exit_code == 0
                # No publish_prefix should be set
                args = mock_aptly.add_packages.call_args
                assert args[0][1] == "jethome-tools"
