import os
import logging
from datetime import timedelta

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .const import DOMAIN, DATA_DIR, SCAN_INTERVAL

_LOGGER = logging.getLogger(__name__)


class SmS4IoTCoordinator(DataUpdateCoordinator):
    """Poll sms4iot/data/<device_id> and expose parsed sensor values."""

    def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
        self.device_id: str = entry.data["device_id"]
        super().__init__(
            hass,
            _LOGGER,
            name=f"{DOMAIN}_{self.device_id}",
            update_interval=timedelta(seconds=SCAN_INTERVAL),
        )

    async def _async_update_data(self) -> dict:
        data_file = self.hass.config.path(DATA_DIR, self.device_id)

        def _read() -> dict:
            if not os.path.exists(data_file):
                return {}
            result: dict = {}
            with open(data_file, "r") as fh:
                for raw in fh:
                    line = raw.strip()
                    if "=" in line:
                        key, _, value = line.partition("=")
                        result[key.strip().lower()] = value.strip()
            return result

        try:
            return await self.hass.async_add_executor_job(_read)
        except OSError as err:
            raise UpdateFailed(f"Error reading {data_file}: {err}") from err

    async def async_write_command(self, command: str) -> None:
        """Atomically write a control command to <device_id>.out."""
        out_file = self.hass.config.path(DATA_DIR, f"{self.device_id}.out")

        def _write():
            tmp = out_file + ".tmp"
            with open(tmp, "w") as fh:
                fh.write(command)
            os.replace(tmp, out_file)

        await self.hass.async_add_executor_job(_write)
        _LOGGER.debug("Wrote command %r to %s", command, out_file)
