"""Tests for the docker module."""

import pytest
from unittest.mock import patch, MagicMock
from cheshire_cat_cli import docker


class TestIsDockerInstalled:
    """Tests for is_docker_installed function."""

    @patch("cheshire_cat_cli.docker.shutil.which")
    def test_docker_installed(self, mock_which):
        """Test when Docker is installed."""
        mock_which.return_value = "/usr/bin/docker"
        assert docker.is_docker_installed() is True
        mock_which.assert_called_once_with("docker")

    @patch("cheshire_cat_cli.docker.shutil.which")
    def test_docker_not_installed(self, mock_which):
        """Test when Docker is not installed."""
        mock_which.return_value = None
        assert docker.is_docker_installed() is False
        mock_which.assert_called_once_with("docker")


class TestIsDockerDaemonRunning:
    """Tests for is_docker_daemon_running function."""

    @patch("cheshire_cat_cli.docker.is_docker_installed")
    def test_docker_not_installed(self, mock_is_installed):
        """Test when Docker is not installed."""
        mock_is_installed.return_value = False
        assert docker.is_docker_daemon_running() is False

    @patch("cheshire_cat_cli.docker.subprocess.run")
    @patch("cheshire_cat_cli.docker.is_docker_installed")
    def test_docker_daemon_running(self, mock_is_installed, mock_run):
        """Test when Docker daemon is running."""
        mock_is_installed.return_value = True
        mock_result = MagicMock()
        mock_result.returncode = 0
        mock_run.return_value = mock_result

        assert docker.is_docker_daemon_running() is True
        mock_run.assert_called_once_with(
            ["docker", "info"],
            capture_output=True,
            text=True,
            timeout=5,
        )

    @patch("cheshire_cat_cli.docker.subprocess.run")
    @patch("cheshire_cat_cli.docker.is_docker_installed")
    def test_docker_daemon_not_running(self, mock_is_installed, mock_run):
        """Test when Docker daemon is not running."""
        mock_is_installed.return_value = True
        mock_result = MagicMock()
        mock_result.returncode = 1
        mock_run.return_value = mock_result

        assert docker.is_docker_daemon_running() is False

    @patch("cheshire_cat_cli.docker.subprocess.run")
    @patch("cheshire_cat_cli.docker.is_docker_installed")
    def test_docker_daemon_timeout(self, mock_is_installed, mock_run):
        """Test when Docker daemon check times out."""
        import subprocess
        mock_is_installed.return_value = True
        mock_run.side_effect = subprocess.TimeoutExpired(cmd=["docker", "info"], timeout=5)

        assert docker.is_docker_daemon_running() is False

    @patch("cheshire_cat_cli.docker.subprocess.run")
    @patch("cheshire_cat_cli.docker.is_docker_installed")
    def test_docker_daemon_file_not_found(self, mock_is_installed, mock_run):
        """Test when Docker command is not found."""
        mock_is_installed.return_value = True
        mock_run.side_effect = FileNotFoundError()

        assert docker.is_docker_daemon_running() is False


class TestCheckDockerAvailability:
    """Tests for check_docker_availability function."""

    @patch("cheshire_cat_cli.docker.is_docker_daemon_running")
    @patch("cheshire_cat_cli.docker.is_docker_installed")
    def test_docker_available(self, mock_is_installed, mock_is_running):
        """Test when Docker is available and running."""
        mock_is_installed.return_value = True
        mock_is_running.return_value = True

        is_available, error_message = docker.check_docker_availability()

        assert is_available is True
        assert error_message == ""

    @patch("cheshire_cat_cli.docker.is_docker_installed")
    def test_docker_not_installed(self, mock_is_installed):
        """Test when Docker is not installed."""
        mock_is_installed.return_value = False

        is_available, error_message = docker.check_docker_availability()

        assert is_available is False
        assert "Docker is not installed" in error_message
        assert "https://docs.docker.com/get-docker/" in error_message

    @patch("cheshire_cat_cli.docker.is_docker_daemon_running")
    @patch("cheshire_cat_cli.docker.is_docker_installed")
    def test_docker_daemon_not_running(self, mock_is_installed, mock_is_running):
        """Test when Docker is installed but daemon is not running."""
        mock_is_installed.return_value = True
        mock_is_running.return_value = False

        is_available, error_message = docker.check_docker_availability()

        assert is_available is False
        assert "Docker daemon is not running" in error_message
        assert "Please start Docker" in error_message
