"""Real hardware interface for {{ module_name }}.

This module provides the real hardware interface for communicating with
the {{ module_name }} device. Replace the TODO placeholders with your
actual instrument-specific code.

Connection type: {{ connection_type }}

Generated by: madsci new interface --type real
Template version: {{ template_version }}
"""

import logging
from typing import Any, Optional

logger = logging.getLogger(__name__)


class {{ module_name | pascal_case }}Interface:
    """Real hardware interface for {{ module_name }}.

    This class handles the actual hardware communication. It provides:
    - Connection lifecycle management (connect/disconnect)
    - Device initialization and shutdown
    - Command execution with error handling
    - Status reporting

    Replace TODO sections with your instrument-specific implementation.

    Example:
        >>> interface = {{ module_name | pascal_case }}Interface(address="192.168.1.100")
        >>> interface.connect()
        >>> interface.initialize()
        >>> result = interface.execute_command("read_data")
        >>> interface.shutdown()
        >>> interface.disconnect()
    """

    def __init__(
        self,
        address: Optional[str] = None,
        port: Optional[int] = None,
        **kwargs: Any,
    ) -> None:
        """Initialize the interface.

        Args:
            address: Device address (IP, serial port, etc.).
            port: Device port number.
            **kwargs: Additional device-specific configuration.
        """
        self._address = address
        self._port = port
        self._config = kwargs
        self._connected = False
        self._initialized = False
        self._connection: Any = None

    @property
    def is_connected(self) -> bool:
        """Check if the interface is connected to the device."""
        return self._connected

    @property
    def is_initialized(self) -> bool:
        """Check if the device has been initialized."""
        return self._initialized

    def connect(self) -> None:
        """Establish connection to the device.

        TODO: Replace with your actual connection logic.

        Raises:
            ConnectionError: If connection fails.
        """
        logger.info(f"Connecting to {{ module_name }} at {self._address}:{self._port}...")

        # TODO: Implement actual connection logic for {{ connection_type }}
        # Example for TCP:
        #   import socket
        #   self._connection = socket.create_connection(
        #       (self._address, self._port), timeout=10.0
        #   )
        #
        # Example for serial:
        #   import serial
        #   self._connection = serial.Serial(
        #       port=self._address, baudrate=9600, timeout=1.0
        #   )

        self._connected = True
        logger.info("Connected to {{ module_name }} device")

    def disconnect(self) -> None:
        """Close connection to the device."""
        if self._connected:
            logger.info("Disconnecting from {{ module_name }} device...")

            # TODO: Close the actual connection
            # Example:
            #   self._connection.close()
            #   self._connection = None

            self._connected = False
            self._initialized = False
            logger.info("Disconnected from {{ module_name }} device")

    def initialize(self) -> None:
        """Initialize the device for operation.

        TODO: Add device-specific initialization (homing, calibration, etc.)

        Raises:
            RuntimeError: If not connected.
        """
        if not self._connected:
            raise RuntimeError("Not connected to device. Call connect() first.")

        logger.info("Initializing {{ module_name }} device...")

        # TODO: Implement device-specific initialization
        # Example:
        #   self._connection.send(b"INIT\\n")
        #   response = self._connection.recv(1024)
        #   if b"OK" not in response:
        #       raise RuntimeError("Initialization failed")

        self._initialized = True
        logger.info("{{ module_name | pascal_case }} device initialized")

    def shutdown(self) -> None:
        """Safely shut down the device.

        Raises:
            RuntimeError: If not connected.
        """
        if not self._connected:
            raise RuntimeError("Not connected to device. Call connect() first.")

        logger.info("Shutting down {{ module_name }} device...")

        # TODO: Implement safe shutdown logic

        self._initialized = False
        logger.info("{{ module_name | pascal_case }} device shut down")

    def execute_command(self, command: str, **kwargs: Any) -> dict:
        """Execute a command on the device.

        Args:
            command: The command to execute.
            **kwargs: Additional command parameters.

        Returns:
            dict: Command result.

        Raises:
            RuntimeError: If not connected or not initialized.
        """
        if not self._connected:
            raise RuntimeError("Not connected to device. Call connect() first.")
        if not self._initialized:
            raise RuntimeError("Device not initialized. Call initialize() first.")

        logger.info(f"Executing command on {{ module_name }}: {command}")

        # TODO: Implement actual command execution
        # Example:
        #   self._connection.send(f"{command}\\n".encode())
        #   response = self._connection.recv(4096)
        #   return {"command": command, "response": response.decode(), "success": True}

        return {
            "command": command,
            "parameters": kwargs,
            "success": True,
        }

    def get_status(self) -> dict:
        """Get the current status of the device.

        Returns:
            dict: Device status information.

        Raises:
            RuntimeError: If not connected.
        """
        if not self._connected:
            raise RuntimeError("Not connected to device. Call connect() first.")

        # TODO: Query actual device status

        return {
            "connected": self._connected,
            "initialized": self._initialized,
            "status_code": 0,
        }
