"""Runner entrypoint for the Neuracore data daemon."""

from __future__ import annotations

import atexit
import logging

from neuracore.data_daemon.bootstrap import DaemonBootstrap, DaemonContext
from neuracore.data_daemon.communications_management.data_bridge import Daemon
from neuracore.data_daemon.const import RECORDING_EVENTS_SOCKET_PATH, SOCKET_PATH
from neuracore.data_daemon.helpers import get_daemon_db_path, get_daemon_pid_path
from neuracore.data_daemon.lifecycle.daemon_lifecycle import (
    install_signal_handlers,
    shutdown,
)

logger = logging.getLogger(__name__)


def main() -> None:
    """Runner entrypoint for the Neuracore data daemon.

    This function bootstraps the daemon, starts it, and then waits for
    a signal to stop. The daemon is stopped when the function returns.

    Environment variables affecting this function:

    NEURACORE_DAEMON_PID_PATH
        Path to the pid file for the daemon.

    NEURACORE_DAEMON_DB_PATH
        Path to the SQLite database file for the daemon's state.

    The daemon will exit with a status code of 1 if the socket at
    NEURACORE_DAEMON_SOCKET_PATH already exists.

    The daemon will shut down when it receives a SIGINT or SIGTERM signal.
    """
    pid_path = get_daemon_pid_path()
    db_path = get_daemon_db_path()

    try:
        bootstrap = DaemonBootstrap(db_path=db_path)
        context = bootstrap.start()

        if not isinstance(context, DaemonContext):
            logger.error("Failed to start daemon")
            return
        install_signal_handlers(lambda _signum: None)
        daemon = Daemon(
            recording_disk_manager=context.recording_disk_manager,
            comm_manager=context.comm_manager,
        )

        def on_exit() -> None:
            """Inform user of daemon exit event."""
            daemon.stop()
            print("Daemon exited.")

        atexit.register(on_exit)
        logger.info("Daemon starting main loop...")
        daemon.run()

    except KeyboardInterrupt:
        logger.info("Received keyboard interrupt")
    except SystemExit:
        pass
    finally:
        bootstrap.stop()
        shutdown(
            pid_path=pid_path,
            socket_paths=(SOCKET_PATH, RECORDING_EVENTS_SOCKET_PATH),
            db_path=db_path,
        )
        print("Daemon stopped.")


if __name__ == "__main__":
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    )
    main()
