"""Fake interface for {{ module_name }} device.

This module provides a simulated interface for testing without hardware.
It implements the same methods as the real interface but operates entirely
in memory, with configurable latency and full state tracking for testing.

Generated by: madsci new module --template module/device
Template version: {{ template_version }}
"""

import logging
import time
from typing import Any, Optional

from {{ module_name }}_types import {{ module_name | pascal_case }}InterfaceConfig

logger = logging.getLogger(__name__)


class {{ module_name | pascal_case }}FakeInterface:
    """Fake interface for testing {{ module_name }} without hardware.

    This class simulates device behavior including full lifecycle management
    (connect, initialize, shutdown, disconnect) and command execution. It is
    designed for:
    - Development without physical hardware
    - Automated testing in CI/CD
    - Demo and training purposes
    - Debugging workflow logic

    Example:
        >>> interface = {{ module_name | pascal_case }}FakeInterface(simulated_latency=0.01)
        >>> interface.connect()
        >>> interface.initialize()
        >>> result = interface.execute_command("test_command", param1="value1")
        >>> status = interface.get_status()
        >>> interface.shutdown()
        >>> interface.disconnect()
    """

    def __init__(
        self,
        config: Optional[{{ module_name | pascal_case }}InterfaceConfig] = None,
        simulated_latency: float = 0.1,
        **kwargs: Any,
    ) -> None:
        """Initialize the fake interface.

        Args:
            config: Interface configuration. Uses defaults if None.
            simulated_latency: Simulated operation time in seconds.
            **kwargs: Additional configuration (ignored in fake mode).
        """
        self._config = config or {{ module_name | pascal_case }}InterfaceConfig(**kwargs)
        self._simulated_latency = simulated_latency
        self._connected = False
        self._initialized = False
        self._operation_count = 0
        self._state: dict[str, Any] = {}
        self._command_history: list[dict[str, Any]] = []

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

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

    @property
    def operation_count(self) -> int:
        """Get the number of operations performed."""
        return self._operation_count

    @property
    def command_history(self) -> list[dict[str, Any]]:
        """Get the history of executed commands."""
        return list(self._command_history)

    def connect(self) -> None:
        """Simulate establishing connection to the device."""
        logger.info("[FAKE] Connecting to simulated {{ module_name }} device...")
        time.sleep(self._simulated_latency)
        self._connected = True
        self._state["connected_at"] = time.time()
        logger.info("[FAKE] Connected to simulated {{ module_name }} device")

    def disconnect(self) -> None:
        """Simulate closing connection to the device."""
        if self._connected:
            logger.info("[FAKE] Disconnecting from simulated {{ module_name }} device...")
            self._connected = False
            self._initialized = False
            self._state["disconnected_at"] = time.time()
            logger.info("[FAKE] Disconnected from simulated {{ module_name }} device")

    def initialize(self) -> None:
        """Simulate device initialization.

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

        logger.info("[FAKE] Initializing simulated {{ module_name }} device...")
        time.sleep(self._simulated_latency)
        self._initialized = True
        self._state["initialized_at"] = time.time()
        logger.info("[FAKE] Simulated {{ module_name }} device initialized")

    def shutdown(self) -> None:
        """Simulate device shutdown.

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

        logger.info("[FAKE] Shutting down simulated {{ module_name }} device...")
        time.sleep(self._simulated_latency)
        self._initialized = False
        self._state["shutdown_at"] = time.time()
        logger.info("[FAKE] Simulated {{ module_name }} device shut down")

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

        Returns:
            dict: Simulated device status information.

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

        return {
            "connected": self._connected,
            "initialized": self._initialized,
            "status_code": 0,
            "operation_count": self._operation_count,
            "last_command": self._state.get("last_command"),
        }

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

        Args:
            command: The command string to execute.
            **kwargs: Additional parameters for the command.

        Returns:
            dict: Simulated command execution result.

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

        time.sleep(self._simulated_latency)

        self._operation_count += 1
        self._state["last_command"] = command
        self._state["last_command_time"] = time.time()

        command_record = {
            "command": command,
            "parameters": kwargs,
            "operation_number": self._operation_count,
            "timestamp": time.time(),
        }
        self._command_history.append(command_record)

        logger.info(f"[FAKE] Simulated command execution: {command}")
        return {
            "command": command,
            "parameters": kwargs,
            "success": True,
            "operation_number": self._operation_count,
        }

    def get_state(self) -> dict[str, Any]:
        """Get the current internal state (useful for testing).

        Returns:
            Dictionary of internal state including connection status,
            initialization status, operation count, and command history.
        """
        return {
            "connected": self._connected,
            "initialized": self._initialized,
            "operation_count": self._operation_count,
            "command_history_length": len(self._command_history),
            **self._state,
        }

    def reset_state(self) -> None:
        """Reset internal state (useful for testing).

        Clears operation count, command history, and internal state
        while preserving connection and initialization status.
        """
        self._operation_count = 0
        self._command_history = []
        self._state = {}
