"""Tests for configuration dataclasses and auto_batch_size."""

from __future__ import annotations

from src.conf.hardware_conf import HardwareConfig
from src.conf.pipeline_conf import PipelineConfig
from src.conf.seg_conf import SegConfig
from src.conf.input_conf import InputConfig


class TestHardwareConfig:
    def test_defaults(self, hw_conf: HardwareConfig) -> None:
        assert hw_conf.available_gb == 7.0
        assert hw_conf.batch_size == 2
        assert hw_conf.use_fp16 is False

    def test_auto_batch_size_returns_manual_when_set(self, hw_conf: HardwareConfig) -> None:
        bs = hw_conf.auto_batch_size(act_per_sample_mb=120)
        assert bs == 2  # manual override

    def test_auto_batch_size_computes_when_none(self) -> None:
        import gin
        gin.clear_config()
        cfg = HardwareConfig(
            total_ram_gb=24.0, reserve_gb=2.0,
            batch_size=None,  # auto
        )
        bs = cfg.auto_batch_size(act_per_sample_mb=120)
        assert bs >= 1
        # Must be power of 2.
        assert (bs & (bs - 1)) == 0

    def test_auto_batch_size_minimum_1(self) -> None:
        import gin
        gin.clear_config()
        cfg = HardwareConfig(total_ram_gb=1.0, reserve_gb=0.5, batch_size=None)
        bs = cfg.auto_batch_size(act_per_sample_mb=1000)
        assert bs >= 1


class TestPipelineConfig:
    def test_default_stages(self, pipeline_conf: PipelineConfig) -> None:
        assert pipeline_conf.stages == ["depth", "edges", "segmentation", "chmv2"]

    def test_save_flags(self, pipeline_conf: PipelineConfig) -> None:
        assert pipeline_conf.save_npy is True
        assert pipeline_conf.save_vis is True
        assert pipeline_conf.save_concat is False


class TestSegConfig:
    def test_num_classes(self, seg_conf: SegConfig) -> None:
        assert seg_conf.num_classes == 3
        assert seg_conf.prompts == ["background", "building", "road"]


class TestInputConfig:
    def test_defaults(self, input_conf: InputConfig) -> None:
        assert input_conf.image_size == 64
        assert len(input_conf.imagenet_mean) == 3
