import io
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest
from PIL import Image

from planemapper.provisioning import ProvisioningError
from planemapper.provisioning.tiles import (
    download_and_composite,
    lat_lon_to_tile,
    validate_cache,
)


def _make_png_bytes() -> bytes:
    img = Image.new("RGB", (256, 256), (200, 200, 200))
    buf = io.BytesIO()
    img.save(buf, format="PNG")
    return buf.getvalue()


def test_lat_lon_to_tile_london() -> None:
    x, y = lat_lon_to_tile(51.5, -0.1, 10)
    assert x == 511
    assert y == 340


def test_download_and_composite(tmp_path: Path) -> None:
    bg_path = tmp_path / "background.png"
    mock_resp = MagicMock()
    mock_resp.content = _make_png_bytes()
    mock_resp.raise_for_status = MagicMock()
    with (
        patch("planemapper.provisioning.tiles.requests.get", return_value=mock_resp),
        patch("planemapper.provisioning.tiles.BACKGROUND_PATH", bg_path),
    ):
        download_and_composite(51.5, -0.1, 100)
    assert bg_path.exists()
    with Image.open(bg_path) as img:
        assert img.size == (800, 480)


def test_validate_cache_passes(tmp_path: Path) -> None:
    bg_path = tmp_path / "background.png"
    Image.new("RGB", (800, 480), (255, 255, 255)).save(str(bg_path))
    with patch("planemapper.provisioning.tiles.BACKGROUND_PATH", bg_path):
        validate_cache()


def test_validate_cache_missing(tmp_path: Path) -> None:
    bg_path = tmp_path / "nonexistent.png"
    with patch("planemapper.provisioning.tiles.BACKGROUND_PATH", bg_path):
        with pytest.raises(ProvisioningError, match="not found"):
            validate_cache()


def test_validate_cache_empty(tmp_path: Path) -> None:
    bg_path = tmp_path / "background.png"
    bg_path.write_bytes(b"")
    with patch("planemapper.provisioning.tiles.BACKGROUND_PATH", bg_path):
        with pytest.raises(ProvisioningError, match="empty"):
            validate_cache()


def test_validate_cache_corrupt(tmp_path: Path) -> None:
    bg_path = tmp_path / "background.png"
    bg_path.write_bytes(b"not a png at all")
    with patch("planemapper.provisioning.tiles.BACKGROUND_PATH", bg_path):
        with pytest.raises(ProvisioningError, match="not a valid PNG"):
            validate_cache()
