"""Tests for internal utility functions (_utils.py)."""

from walkingpandas._utils import (
    BoundingBox,
    _escape_sql_string,
    _format_id_list_sql,
    generate_cache_key,
)


def test_escape_sql_string_no_quotes():
    assert _escape_sql_string("hello") == "hello"


def test_escape_sql_string_with_quotes():
    assert _escape_sql_string("it's") == "it''s"


def test_format_id_list_sql_empty():
    assert _format_id_list_sql([]) == ""


def test_format_id_list_sql_integers():
    assert _format_id_list_sql([1, 2, 3]) == "1, 2, 3"


def test_format_id_list_sql_strings():
    result = _format_id_list_sql(["Station_A", "Station_B"])
    assert result == "'Station_A', 'Station_B'"


def test_format_id_list_sql_strings_with_quotes():
    result = _format_id_list_sql(["it's", "fine"])
    assert result == "'it''s', 'fine'"


def test_format_id_list_sql_mixed():
    result = _format_id_list_sql([1, "two", 3])
    assert "'1'" in result
    assert "'two'" in result
    assert "'3'" in result


# ---------------------------------------------------------------------------
# BoundingBox tests
# ---------------------------------------------------------------------------


def test_bounding_box_from_nsew():
    bb = BoundingBox.from_nsew(47.4, 47.3, 8.6, 8.5)
    assert bb.north == 47.4
    assert bb.south == 47.3
    assert bb.east == 8.6
    assert bb.west == 8.5
    assert bb.as_nsew() == (47.4, 47.3, 8.6, 8.5)


def test_bounding_box_from_min_max():
    bb = BoundingBox.from_min_max(min_lon=8.5, min_lat=47.3, max_lon=8.6, max_lat=47.4)
    assert bb.north == 47.4
    assert bb.south == 47.3
    assert bb.east == 8.6
    assert bb.west == 8.5


def test_bounding_box_as_osmium():
    bb = BoundingBox.from_nsew(47.4, 47.3, 8.6, 8.5)
    assert bb.as_osmium() == "8.5,47.3,8.6,47.4"


def test_bounding_box_as_overpass():
    bb = BoundingBox.from_nsew(47.4, 47.3, 8.6, 8.5)
    assert bb.as_overpass() == "47.3,8.5,47.4,8.6"


def test_bounding_box_contains():
    bb = BoundingBox.from_nsew(47.4, 47.3, 8.6, 8.5)
    assert bb.contains(lon=8.55, lat=47.35)
    assert bb.contains(lon=8.5, lat=47.3)
    assert bb.contains(lon=8.6, lat=47.4)
    assert not bb.contains(lon=8.49, lat=47.35)
    assert not bb.contains(lon=8.55, lat=47.41)
    assert not bb.contains(lon=8.61, lat=47.35)
    assert not bb.contains(lon=8.55, lat=47.29)


def test_bounding_box_is_frozen():
    import pytest
    bb = BoundingBox.from_nsew(47.4, 47.3, 8.6, 8.5)
    with pytest.raises(AttributeError):
        bb.north = 99.0


# ---------------------------------------------------------------------------
# generate_cache_key tests
# ---------------------------------------------------------------------------


def test_generate_cache_key_osm_pbf_existing(tmp_path):
    pbf = tmp_path / "test.osm.pbf"
    pbf.write_bytes(b"fake pbf data")
    key = generate_cache_key(osm_pbf=pbf)
    assert isinstance(key, str) and len(key) == 16


def test_generate_cache_key_osm_pbf_missing(tmp_path):
    pbf = tmp_path / "missing.osm.pbf"
    key = generate_cache_key(osm_pbf=pbf)
    assert isinstance(key, str) and len(key) == 16


def test_generate_cache_key_osm_pbf_existing_vs_missing_differ(tmp_path):
    pbf = tmp_path / "test.osm.pbf"
    key_missing = generate_cache_key(osm_pbf=pbf)
    pbf.write_bytes(b"data")
    key_exists = generate_cache_key(osm_pbf=pbf)
    assert key_missing != key_exists
