"""Tests for MakePython commands."""

from __future__ import annotations

from pathlib import Path

import pytest

from ..commands.impl.clean import CleanCommand
from ..commands.impl.init import InitCommand
from ..commands.impl.lint import LintCommand
from ..commands.impl.update import UpdateCommand
from ..core.context import ExecutionContext
from ..core.factory import initialize_command_system
from ..core.registry import get_registry


@pytest.fixture
def context(tmp_path: Path) -> ExecutionContext:
    """Create execution context for testing."""
    return ExecutionContext(cwd=tmp_path)


class TestCleanCommand:
    """Tests for CleanCommand."""

    def test_clean_command_initialization(self):
        """Test CleanCommand initialization."""
        cmd = CleanCommand()
        assert cmd.name == "clean"
        assert cmd.alias == "c"
        assert cmd.command_type.value == "clean"

    def test_clean_command_validate(self, context: ExecutionContext):
        """Test CleanCommand validation."""
        cmd = CleanCommand()
        # Should always validate successfully
        assert cmd.validate(context) is True

    def test_clean_command_execute_empty_dir(self, context: ExecutionContext):
        """Test CleanCommand execution on empty directory."""
        cmd = CleanCommand()
        result = cmd.execute(context)

        assert result.success is True
        assert "cleaned" in result.message.lower()


class TestLintCommand:
    """Tests for LintCommand."""

    def test_lint_command_initialization(self):
        """Test LintCommand initialization."""
        cmd = LintCommand()
        assert cmd.name == "lint"
        assert cmd.alias == "l"
        assert cmd.command_type.value == "util"

    def test_lint_command_validate(self, context: ExecutionContext):
        """Test LintCommand validation."""
        cmd = LintCommand()
        # Should validate even if ruff not found (will warn but continue)
        assert cmd.validate(context) is True


class TestUpdateCommand:
    """Tests for UpdateCommand."""

    def test_update_command_initialization(self):
        """Test UpdateCommand initialization."""
        cmd = UpdateCommand()
        assert cmd.name == "update"
        assert cmd.alias == "u"
        assert cmd.command_type.value == "util"

    def test_update_command_validate(self, context: ExecutionContext):
        """Test UpdateCommand validation."""
        cmd = UpdateCommand()
        # Should validate even without pyproject.toml
        assert cmd.validate(context) is True

    def test_update_command_execute_no_init_files(self, context: ExecutionContext):
        """Test UpdateCommand execution with no __init__.py files."""
        cmd = UpdateCommand()
        result = cmd.execute(context)

        assert result.success is True
        assert "no files" in result.message.lower() or "updated" in result.message.lower()


class TestInitCommand:
    """Tests for InitCommand."""

    def test_init_command_initialization(self):
        """Test InitCommand initialization."""
        cmd = InitCommand()
        assert cmd.name == "init"
        assert cmd.alias == "i"
        assert cmd.command_type.value == "util"

    def test_init_command_validate(self, context: ExecutionContext):
        """Test InitCommand validation."""
        cmd = InitCommand()
        # Should always validate
        assert cmd.validate(context) is True


class TestCommandRegistry:
    """Tests for command registry."""

    def test_registry_initialization(self):
        """Test that command system initializes properly."""
        # This should not raise any exceptions
        initialize_command_system()

        registry = get_registry()
        assert registry is not None

    def test_registered_commands(self):
        """Test that commands are registered."""
        initialize_command_system()

        registry = get_registry()
        commands = registry.list_commands()

        # Check core commands are registered
        assert "build" in commands
        assert "clean" in commands
        assert "test" in commands

        # Check utility commands are registered
        assert "lint" in commands
        assert "doc" in commands
        assert "update" in commands
        assert "init" in commands

    def test_command_aliases(self):
        """Test command aliases."""
        initialize_command_system()

        registry = get_registry()
        aliases = registry.list_aliases()

        # Check some common aliases
        assert "b" in aliases  # build
        assert "c" in aliases  # clean
        assert "t" in aliases  # test
        assert "l" in aliases  # lint
