"""Tests for LocalBuildpackChain."""

from __future__ import annotations

from pathlib import Path
from unittest.mock import MagicMock

import pytest

from djb.buildpacks.constants import BuildpackError
from djb.buildpacks.local import LocalBuildpackChain

# Note: TestLocalBuildpackChainBuildImage moved to e2e/test_local_chain.py


class TestLocalBuildpackChainImageExists:
    """Tests for LocalBuildpackChain.image_exists()."""

    def test_image_exists_returns_true(self, mock_cmd_runner: MagicMock) -> None:
        """image_exists() returns True when docker inspect succeeds."""
        mock_cmd_runner.check.return_value = True
        chain = LocalBuildpackChain(
            registry="k3d-registry.localhost:5000",
            runner=mock_cmd_runner,
        )

        assert chain.image_exists("k3d-registry.localhost:5000/test:latest") is True

    def test_image_exists_returns_false(self, mock_cmd_runner: MagicMock) -> None:
        """image_exists() returns False when docker inspect fails."""
        mock_cmd_runner.check.return_value = False
        chain = LocalBuildpackChain(
            registry="k3d-registry.localhost:5000",
            runner=mock_cmd_runner,
        )

        assert chain.image_exists("k3d-registry.localhost:5000/test:latest") is False

    def test_image_exists_uses_docker_inspect(self, mock_cmd_runner: MagicMock) -> None:
        """image_exists() uses docker image inspect."""
        mock_cmd_runner.check.return_value = True
        chain = LocalBuildpackChain(
            registry="k3d-registry.localhost:5000",
            runner=mock_cmd_runner,
        )

        chain.image_exists("k3d-registry.localhost:5000/test:latest")

        mock_cmd_runner.check.assert_called_once()
        call_args = mock_cmd_runner.check.call_args[0][0]
        assert call_args == [
            "docker",
            "image",
            "inspect",
            "k3d-registry.localhost:5000/test:latest",
        ]


class TestLocalBuildpackChainBuild:
    """Tests for LocalBuildpackChain.build()."""

    def test_build_returns_cached_image(
        self, mock_cmd_runner: MagicMock, make_pyproject_with_gdal: Path
    ) -> None:
        """build() returns existing image without rebuilding."""
        # Image exists
        mock_cmd_runner.check.return_value = True
        chain = LocalBuildpackChain(
            registry="k3d-registry.localhost:5000",
            runner=mock_cmd_runner,
            pyproject_path=make_pyproject_with_gdal,
        )

        result = chain.build(["python:3.14-slim"])

        assert result == "k3d-registry.localhost:5000/python3.14-slim:latest"
        # Only called once to check if image exists
        assert mock_cmd_runner.check.call_count == 1

    def test_build_empty_buildpacks_raises(self, mock_cmd_runner: MagicMock) -> None:
        """build() raises BuildpackError for empty buildpack list."""
        chain = LocalBuildpackChain(
            registry="k3d-registry.localhost:5000",
            runner=mock_cmd_runner,
        )

        with pytest.raises(BuildpackError, match="No buildpacks specified"):
            chain.build([])

    def test_build_first_public_image_not_built(
        self, mock_cmd_runner: MagicMock, make_pyproject_with_gdal: Path
    ) -> None:
        """build() uses first public image as-is without building."""
        # Image doesn't exist
        mock_cmd_runner.check.return_value = False
        chain = LocalBuildpackChain(
            registry="k3d-registry.localhost:5000",
            runner=mock_cmd_runner,
            pyproject_path=make_pyproject_with_gdal,
        )

        result = chain.build(["python:3.14-slim"])

        # Should return the public image directly
        assert result == "python:3.14-slim"
