"""
map_persistence.launch.py — Map save/load lifecycle nodes (Issue #696).

Launches:
  1. map_saver_server  — nav2_map_server lifecycle node; exposes
                         /map_saver/save_map action (nav2_msgs/action/SaveMap)
  2. saltybot_map_saver — helper node: /saltybot/save_map Trigger service,
                          startup check, optional auto-save on shutdown
  3. lifecycle_manager_map_saver — manages map_saver_server transitions

Arguments
─────────
  map_dir      path to map storage directory
               (default: /mnt/nvme/saltybot/maps)
  map_name     base filename for saved map, no extension
               (default: saltybot_map)
  use_sim_time (default: false)
  autostart    lifecycle manager autostart (default: true)

Save a map (CLI shortcut while SLAM is running):
  ros2 service call /saltybot/save_map std_srvs/srv/Trigger {}

Or directly via map_saver_cli:
  ros2 run nav2_map_server map_saver_cli \\
      -f /mnt/nvme/saltybot/maps/saltybot_map --map_subscribe_transient_local

Load on next startup:
  ros2 launch saltybot_nav2_slam nav2_amcl_bringup.launch.py
      # auto-detects /mnt/nvme/saltybot/maps/saltybot_map.yaml if present
"""

import os

from ament_index_python.packages import get_package_share_directory

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, LogInfo
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node


def generate_launch_description() -> LaunchDescription:
    nav2_slam_dir = get_package_share_directory("saltybot_nav2_slam")
    map_saver_params = os.path.join(nav2_slam_dir, "config", "map_saver_params.yaml")

    # ── Arguments ─────────────────────────────────────────────────────────────

    map_dir_arg = DeclareLaunchArgument(
        "map_dir",
        default_value="/mnt/nvme/saltybot/maps",
        description="Directory for saving/loading map files (.yaml + .pgm)",
    )

    map_name_arg = DeclareLaunchArgument(
        "map_name",
        default_value="saltybot_map",
        description="Base filename for saved map (no extension)",
    )

    use_sim_time_arg = DeclareLaunchArgument(
        "use_sim_time",
        default_value="false",
        description="Use simulated clock",
    )

    autostart_arg = DeclareLaunchArgument(
        "autostart",
        default_value="true",
        description="Automatically configure/activate lifecycle nodes",
    )

    # ── Substitutions ─────────────────────────────────────────────────────────

    map_dir      = LaunchConfiguration("map_dir")
    map_name     = LaunchConfiguration("map_name")
    use_sim_time = LaunchConfiguration("use_sim_time")
    autostart    = LaunchConfiguration("autostart")

    # ── map_saver_server (nav2_map_server lifecycle node) ─────────────────────
    # Exposes /map_saver/save_map action server when active.

    map_saver_server = Node(
        package="nav2_map_server",
        executable="map_saver_server",
        name="map_saver",
        output="screen",
        respawn=True,
        respawn_delay=2.0,
        parameters=[
            map_saver_params,
            {"use_sim_time": use_sim_time},
        ],
    )

    # ── saltybot_map_saver helper node ────────────────────────────────────────
    # /saltybot/save_map Trigger service + startup reporting + auto-save.

    map_saver_helper = Node(
        package="saltybot_nav2_slam",
        executable="map_saver_node",
        name="saltybot_map_saver",
        output="screen",
        parameters=[
            {
                "map_dir":              map_dir,
                "map_name":             map_name,
                "auto_save_on_shutdown": True,
                "use_sim_time":         use_sim_time,
            }
        ],
    )

    # ── Lifecycle manager for map_saver_server ────────────────────────────────

    lifecycle_manager = Node(
        package="nav2_lifecycle_manager",
        executable="lifecycle_manager",
        name="lifecycle_manager_map_saver",
        output="screen",
        parameters=[
            {
                "use_sim_time": use_sim_time,
                "autostart":    autostart,
                "node_names":   ["map_saver"],
            }
        ],
    )

    return LaunchDescription([
        # Arguments
        map_dir_arg,
        map_name_arg,
        use_sim_time_arg,
        autostart_arg,

        # Banner
        LogInfo(msg="[map_persistence] Starting map_saver_server + helper (Issue #696)"),

        # Nodes
        map_saver_server,
        map_saver_helper,
        lifecycle_manager,
    ])
