"""social_test.launch.py — Launch social-bot stack in test/CI mode.

Differences from production social_bot.launch.py:
  - speech/TTS disabled by default (no mic/speaker in CI)
  - LLM disabled by default (no model file in CI; use CI_FULL=1 to enable)
  - mock_sensor_pub node started automatically
  - Shorter TimerAction delays (2s instead of production delays)
  - ROS_DOMAIN_ID isolated to avoid collision with other test runs

Env vars:
  SOCIAL_TEST_FULL=1   — enable speech + LLM + TTS (requires GPU + models)
  SOCIAL_TEST_SPEECH=1 — enable speech pipeline only
"""

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import (
    DeclareLaunchArgument, GroupAction, LogInfo, TimerAction, SetEnvironmentVariable
)
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration, PythonExpression, EnvironmentVariable
from launch_ros.actions import Node

_FULL = os.environ.get("SOCIAL_TEST_FULL", "0") == "1"
_SPEECH = _FULL or os.environ.get("SOCIAL_TEST_SPEECH", "0") == "1"


def generate_launch_description() -> LaunchDescription:
    social_pkg = get_package_share_directory("saltybot_social")
    tests_pkg  = get_package_share_directory("saltybot_social_tests")

    args = [
        DeclareLaunchArgument("enable_speech",       default_value="true" if _SPEECH else "false"),
        DeclareLaunchArgument("enable_llm",          default_value="true" if _FULL else "false"),
        DeclareLaunchArgument("enable_tts",          default_value="true" if _FULL else "false"),
        DeclareLaunchArgument("enable_orchestrator", default_value="true"),
        DeclareLaunchArgument("enable_face",         default_value="true"),
        DeclareLaunchArgument("enable_tracking",     default_value="true"),
        DeclareLaunchArgument("enable_nav",          default_value="true"),
        DeclareLaunchArgument("enable_mock_sensors", default_value="true"),
    ]

    # ── Mock sensor publisher (always first) ─────────────────────────────────
    mock_sensors = Node(
        package="saltybot_social_tests",
        executable="mock_sensor_pub",
        name="mock_sensor_pub",
        output="screen",
        condition=IfCondition(LaunchConfiguration("enable_mock_sensors")),
    )

    # ── Orchestrator (t=0s) ──────────────────────────────────────────────────
    orchestrator = Node(
        package="saltybot_social",
        executable="orchestrator_node",
        name="orchestrator_node",
        parameters=[
            os.path.join(social_pkg, "config", "orchestrator_params.yaml"),
            {"watchdog_timeout_s": 60.0,   # more lenient in CI
             "gpu_mem_throttle_mb": 500.0}, # low floor for CI without GPU
        ],
        condition=IfCondition(LaunchConfiguration("enable_orchestrator")),
        output="screen",
    )

    # ── Face recognition (t=1s) ──────────────────────────────────────────────
    face = TimerAction(period=1.0, actions=[
        GroupAction(
            condition=IfCondition(LaunchConfiguration("enable_face")),
            actions=[
                LogInfo(msg="[social_test] Starting face recognition..."),
                Node(
                    package="saltybot_social_face",
                    executable="face_recognition",
                    name="face_recognition_node",
                    parameters=[{"use_trt": False,       # CPU ONNX in CI
                                 "detection_threshold": 0.5,
                                 "gallery_path": "/tmp/social_test_gallery"}],
                    output="screen",
                ),
            ]
        )
    ])

    # ── Tracking fusion (t=1s) ───────────────────────────────────────────────
    tracking = TimerAction(period=1.0, actions=[
        GroupAction(
            condition=IfCondition(LaunchConfiguration("enable_tracking")),
            actions=[
                Node(
                    package="saltybot_social_tracking",
                    executable="tracking_fusion_node",
                    name="tracking_fusion_node",
                    output="screen",
                ),
            ]
        )
    ])

    # ── Speech pipeline (t=2s, optional) ────────────────────────────────────
    speech = TimerAction(period=2.0, actions=[
        GroupAction(
            condition=IfCondition(LaunchConfiguration("enable_speech")),
            actions=[
                LogInfo(msg="[social_test] Starting speech pipeline..."),
                Node(
                    package="saltybot_social",
                    executable="speech_pipeline_node",
                    name="speech_pipeline_node",
                    parameters=[
                        os.path.join(social_pkg, "config", "speech_params.yaml"),
                        {"whisper_model": "tiny",   # faster in CI
                         "use_silero_vad": False},  # avoid download in CI
                    ],
                    output="screen",
                ),
            ]
        )
    ])

    # ── LLM + TTS (t=3s, optional) ──────────────────────────────────────────
    llm = TimerAction(period=3.0, actions=[
        GroupAction(
            condition=IfCondition(LaunchConfiguration("enable_llm")),
            actions=[
                Node(
                    package="saltybot_social",
                    executable="conversation_node",
                    name="conversation_node",
                    parameters=[
                        os.path.join(social_pkg, "config", "conversation_params.yaml"),
                    ],
                    output="screen",
                ),
            ]
        )
    ])

    tts = TimerAction(period=3.0, actions=[
        GroupAction(
            condition=IfCondition(LaunchConfiguration("enable_tts")),
            actions=[
                Node(
                    package="saltybot_social",
                    executable="tts_node",
                    name="tts_node",
                    parameters=[
                        os.path.join(social_pkg, "config", "tts_params.yaml"),
                        {"playback_enabled": False},  # no speaker in CI
                    ],
                    output="screen",
                ),
            ]
        )
    ])

    # ── Social nav (t=2s) ────────────────────────────────────────────────────
    nav = TimerAction(period=2.0, actions=[
        GroupAction(
            condition=IfCondition(LaunchConfiguration("enable_nav")),
            actions=[
                Node(
                    package="saltybot_social_nav",
                    executable="social_nav",
                    name="social_nav_node",
                    parameters=[{"use_midas_depth": False}],  # no GPU depth in CI
                    output="screen",
                ),
            ]
        )
    ])

    return LaunchDescription(args + [
        mock_sensors, orchestrator,
        face, tracking, speech, llm, tts, nav,
    ])
