"""Tests for tondortools.satellites — satellite_band lookup and validation."""
import pytest

from tondortools.satellites import satellite_band


@pytest.fixture
def sb():
    return satellite_band()


# ---------------------------------------------------------------------------
# landsat_band_lookup
# ---------------------------------------------------------------------------

class TestLandsatBandLookup:
    def test_landsat9_nir(self, sb):
        assert sb.landsat_band_lookup("landsat-9", "nir") == "SR_B5"

    def test_landsat9_vis_r(self, sb):
        assert sb.landsat_band_lookup("landsat-9", "vis-r") == "SR_B4"

    def test_landsat8_same_as_landsat9(self, sb):
        # Landsat-8 and Landsat-9 have identical band mappings.
        for band in ("vis-b", "vis-g", "vis-r", "nir", "swir1", "swir2"):
            assert sb.landsat_band_lookup("landsat-8", band) == sb.landsat_band_lookup("landsat-9", band)

    def test_landsat7_vis_b_is_b1(self, sb):
        assert sb.landsat_band_lookup("landsat-7", "vis-b") == "SR_B1"

    def test_landsat5_vis_b_is_b1(self, sb):
        assert sb.landsat_band_lookup("landsat-5", "vis-b") == "SR_B1"

    def test_landsat_a_scl(self, sb):
        assert sb.landsat_band_lookup("landsat-a", "scl") == "clear_sky_mask"

    def test_invalid_satellite_raises(self, sb):
        with pytest.raises(KeyError):
            sb.landsat_band_lookup("landsat-99", "nir")

    def test_invalid_band_raises(self, sb):
        with pytest.raises(KeyError):
            sb.landsat_band_lookup("landsat-8", "nonexistent_band")


# ---------------------------------------------------------------------------
# sentinel2_band_lookup
# ---------------------------------------------------------------------------

class TestSentinel2BandLookup:
    def test_20m_returns_20m_band(self, sb):
        assert sb.sentinel2_band_lookup("vis-b", 20) == "B02_20m"

    def test_above_20m_returns_20m_band(self, sb):
        assert sb.sentinel2_band_lookup("nir", 30) == "B8A_20m"

    def test_10m_returns_10m_band_when_available(self, sb):
        assert sb.sentinel2_band_lookup("vis-b", 10) == "B02_10m"

    def test_10m_falls_back_to_20m_for_20m_only_bands(self, sb):
        # swir1 is only in the 20m table; at 10m it should fall back.
        assert sb.sentinel2_band_lookup("swir1", 10) == "B11_20m"

    def test_re_bands_only_at_20m(self, sb):
        assert sb.sentinel2_band_lookup("re-705", 20) == "B05_20m"
        assert sb.sentinel2_band_lookup("re-740", 20) == "B06_20m"
        assert sb.sentinel2_band_lookup("re-781", 20) == "B07_20m"

    def test_swir2_at_20m(self, sb):
        assert sb.sentinel2_band_lookup("swir2", 20) == "B12_20m"

    def test_nir_at_10m(self, sb):
        assert sb.sentinel2_band_lookup("nir", 10) == "B08_10m"

    def test_invalid_band_raises_at_20m(self, sb):
        with pytest.raises(KeyError):
            sb.sentinel2_band_lookup("nonexistent", 20)


# ---------------------------------------------------------------------------
# satellite_band_check
# ---------------------------------------------------------------------------

class TestSatelliteBandCheck:
    def test_valid_landsat_band_no_error(self, sb):
        sb.satellite_band_check("nir", ["landsat-8"])  # should not raise

    def test_invalid_landsat_band_raises(self, sb):
        with pytest.raises(Exception, match="doesnot have data"):
            sb.satellite_band_check("re-705", ["landsat-8"])

    def test_valid_sentinel2_band_no_error(self, sb):
        sb.satellite_band_check("vis-b", ["sentinel-2"])  # should not raise

    def test_mixed_satellite_list_valid(self, sb):
        sb.satellite_band_check("nir", ["landsat-8", "sentinel-2"])  # should not raise

    def test_mixed_satellite_list_invalid_for_landsat(self, sb):
        with pytest.raises(Exception):
            sb.satellite_band_check("re-705", ["landsat-8", "sentinel-2"])


# ---------------------------------------------------------------------------
# satellite_bandlist_check
# ---------------------------------------------------------------------------

class TestSatelliteBandlistCheck:
    def test_valid_bandlist_no_error(self, sb):
        sb.satellite_bandlist_check(["nir", "swir1", "vis-r"], ["landsat-8"])

    def test_invalid_band_in_list_raises(self, sb):
        with pytest.raises(Exception):
            sb.satellite_bandlist_check(["nir", "re-705"], ["landsat-8"])

    def test_empty_bandlist_no_error(self, sb):
        sb.satellite_bandlist_check([], ["landsat-8"])
