import csv
import json

from bubblecam import state_lib
from conftest import load_bin_module

sensor_logger = load_bin_module("sensor_logger")


def test_open_new_segment_creates_file_with_header(tmp_path):
    f, writer, path = sensor_logger.open_new_segment(tmp_path)
    try:
        assert path.parent == tmp_path
        assert path.name.startswith("sensors_")
        assert path.suffix == ".csv"
    finally:
        f.close()

    with open(path) as fh:
        header = next(csv.reader(fh))
    assert header == sensor_logger.CSV_HEADER


def test_csv_header_includes_lumen_and_power_columns():
    assert "lumen_brightness_pct" in sensor_logger.CSV_HEADER
    assert sensor_logger.CSV_HEADER[-3:] == ["ina219_bus_v", "ina219_current_a", "ina219_power_w"]


def test_bme280_reader_sim_mode_returns_plausible_readings(sim_env):
    from bubblecam.hardware.bme280 import BME280Reader

    reader = BME280Reader()
    reading = reader.read()
    assert 0 < reading["temperature_c"] < 50
    assert 0 <= reading["humidity_pct"] <= 100
    assert 900 < reading["pressure_hpa"] < 1100


def test_ina219_sim_mode_returns_plausible_readings(sim_env):
    from bubblecam.hardware.ina219 import INA219Reader

    reading = INA219Reader().read()
    assert 4.5 < reading["bus_v"] < 5.5
    assert 0 <= reading["current_a"] < 1.0
    assert reading["power_w"] > 0


def test_ina219_fields_from_live_reader(sim_env):
    from bubblecam.hardware.ina219 import INA219Reader

    fields = sensor_logger.ina219_fields(INA219Reader())
    assert len(fields) == 3
    assert all(isinstance(v, float) for v in fields)


def test_ina219_fields_blank_when_chip_absent(sim_env):
    # No INA219 wired up: blank cells ("unknown"), never a fake 0V/0A --
    # same convention as the lumen column.
    assert sensor_logger.ina219_fields(None) == ["", "", ""]


def test_ina219_fields_blank_on_read_fault(sim_env):
    from bubblecam.hardware.ina219 import PowerSensorError

    class FailingReader:
        def read(self):
            raise PowerSensorError("i2c fault")

    assert sensor_logger.ina219_fields(FailingReader()) == ["", "", ""]


def test_lumen_brightness_reads_live_value(sim_env):
    state_lib.write_state("lumen", "running", dark=True, brightness_pct=30.0)
    assert sensor_logger.lumen_brightness_pct() == "30.0"


def test_lumen_brightness_zero_when_lights_off(sim_env):
    # Daylight: a real, trustworthy 0 -- distinct from "unknown".
    state_lib.write_state("lumen", "running", dark=False, brightness_pct=0.0)
    assert sensor_logger.lumen_brightness_pct() == "0.0"


def test_lumen_brightness_blank_when_service_absent(sim_env):
    assert sensor_logger.lumen_brightness_pct() == ""


def test_lumen_brightness_blank_when_stale(sim_env):
    # A dead lumen service must not be logged as 0% (a false assertion that
    # the lights were off) -- an empty cell honestly means "unknown".
    state_lib.write_state("lumen", "running", brightness_pct=30.0)
    state = state_lib.read_state("lumen")
    state["last_update"] -= 999
    (sim_env["state_dir"] / "lumen.json").write_text(json.dumps(state))
    assert sensor_logger.lumen_brightness_pct() == ""


def test_lumen_brightness_blank_when_field_missing(sim_env):
    state_lib.write_state("lumen", "error", detail="pwm fault")
    assert sensor_logger.lumen_brightness_pct() == ""
