"""Device configuration controller."""

from __future__ import annotations

import logging

from ..enums import PacketType
from ..exceptions import ParseError
from ..models import DeviceConfigVariant, Packet
from ..protocol import parse_device_config
from ..session import LibreVNASession

logger = logging.getLogger(__name__)


class ConfigController:
    """Device configuration read/write/reset operations."""

    def __init__(self, session: LibreVNASession) -> None:
        """Bind controller to an active session."""
        self._session = session

    def get(self, *, timeout_s: float = 1.0) -> DeviceConfigVariant:
        """Read configuration block for active hardware family."""
        packet = self._session.request(
            PacketType.REQUEST_DEVICE_CONFIGURATION,
            PacketType.DEVICE_CONFIGURATION,
            timeout_s=timeout_s,
        )
        if not isinstance(packet.payload, (bytes, bytearray, memoryview)):
            raise ParseError("DeviceConfiguration payload has unexpected type")
        cfg = parse_device_config(bytes(packet.payload), self._session.hardware_family)
        logger.info(
            "Loaded device configuration for family=%s fields=%d",
            cfg.family.name,
            len(cfg.values),
        )
        return cfg

    def set(self, cfg: DeviceConfigVariant, *, timeout_s: float = 1.0) -> None:
        """Write configuration block for active hardware family."""
        if cfg.family != self._session.hardware_family:
            raise ParseError("DeviceConfigVariant family does not match connected hardware family")
        logger.info(
            "Writing device configuration for family=%s fields=%d",
            cfg.family.name,
            len(cfg.values),
        )
        self._session.send(Packet(PacketType.DEVICE_CONFIGURATION, cfg), require_ack=True, timeout_s=timeout_s)

    def reset(self, *, timeout_s: float = 1.0) -> None:
        """Reset device configuration to firmware defaults."""
        logger.warning("Resetting device configuration to firmware defaults")
        self._session.send(Packet(PacketType.RESET_DEVICE_CONFIGURATION), require_ack=True, timeout_s=timeout_s)
