"""
Main application class for Sentinel.
"""
import time
import signal
import sys

from config.settings import (
    ACQUISITION_INTERVAL_SECONDS,
    APPLICATION_NAME,
    DATABASE_PATH,
    DATA_DIRECTORY,
    DEVICE_ID,
    EQUIPMENT_ID,
    LOG_DIRECTORY,
    LOG_FILE_PATH,
    VERSION,
)

from sentinel.database.manager import DatabaseManager
from sentinel.acquisition.service import AcquisitionService
from sentinel.sensors.simulated import (
    SimulatedCurrentSensor,
    SimulatedTemperatureSensor,
)
from sentinel.utils.logger import setup_logger


class SentinelApplication:
    """
    Main application controller.

    This class is responsible for starting and coordinating
    all Sentinel services.
    """
    def __init__(self) -> None:
        """
        Initialize the Sentinel application.
        """
        self._running = True

    def _stop(self) -> None:
        """
        Stop the Sentinel application.
        """
        self._running = False

    def _handle_signal(self, signum, frame) -> None:
        """
        Handle an operating system stop signal.
        """
        self._stop()
        
    def run(self) -> None:
        """
        Start the Sentinel application.
        """
        self._prepare_directories()

        logger = setup_logger(LOG_FILE_PATH)

        signal.signal(signal.SIGINT, self._handle_signal)
        signal.signal(signal.SIGTERM, self._handle_signal)

        database = DatabaseManager(DATABASE_PATH)
        database.initialize()
        database.register_device(
            device_id=DEVICE_ID,
            equipment_id=EQUIPMENT_ID,
        )

        ambient_sensor = SimulatedTemperatureSensor(22.0)
        internal_sensor = SimulatedTemperatureSensor(-20.0)
        evaporator_sensor = SimulatedTemperatureSensor(-28.0)
        compressor_sensor = SimulatedTemperatureSensor(48.0)
        current_sensor = SimulatedCurrentSensor(1.9)

        acquisition_service = AcquisitionService(
            ambient_sensor=ambient_sensor,
            internal_sensor=internal_sensor,
            evaporator_sensor=evaporator_sensor,
            compressor_sensor=compressor_sensor,
            current_sensor=current_sensor,
        )

        print("=" * 40)
        print(f" {APPLICATION_NAME} v{VERSION}")
        print("=" * 40)

        logger.info("Starting Sentinel...")
        logger.info("Device ID: %s", DEVICE_ID)
        logger.info("Equipment ID: %s", EQUIPMENT_ID)
        logger.info("Database initialized: %s", DATABASE_PATH)

        while self._running:
            measurement = acquisition_service.acquire()

            database.insert_measurement(
                device_id=DEVICE_ID,
                equipment_id=EQUIPMENT_ID,
                ambient_temperature_c=measurement.ambient_temperature_c,
                internal_temperature_c=measurement.internal_temperature_c,
                evaporator_temperature_c=measurement.evaporator_temperature_c,
                compressor_temperature_c=measurement.compressor_temperature_c,
                compressor_current_a=measurement.compressor_current_a,
                health_score=measurement.health_score,
            )
            logger.info(
                "Measurement stored: internal=%.2f°C current=%.3fA",
                measurement.internal_temperature_c,
                measurement.compressor_current_a,
            )

            time.sleep(ACQUISITION_INTERVAL_SECONDS)

        logger.info("Sentinel stopped.")

    def _prepare_directories(self) -> None:
        """
        Create the runtime directories required by Sentinel.
        """
        DATA_DIRECTORY.mkdir(parents=True, exist_ok=True)
        LOG_DIRECTORY.mkdir(parents=True, exist_ok=True)