/**
 * @file drag_teach_cli_config.h
 * @brief RM75 拖动示教录制程序命令行参数解析接口。
 *
 * @author mashiro
 * @date 2026-07-09
 * @last_modified 2026-07-09
 *
 * @details
 * 本文件声明 `rm_drag_teach_record` 的 CLI 配置结构和解析函数。拖动示教会访问
 * 真实机械臂，因此入口文件必须先得到清晰、可验证的参数配置，再显式建立硬件连接。
 *
 * 设计原则：
 * - 参数解析不连接机械臂；
 * - 参数解析不启动拖动示教；
 * - 默认使用普通记录拖动模式，确保厂商保存接口有明确记录契约；
 * - 保持原有位置参数和选项语义不变。
 *
 * @dependencies
 * - rm_control/common/result.h
 * - rm_control/core/drag_teach_recorder.h
 *
 * @note
 * 后续增加人工确认、dry-run 或安全开关时，应优先扩展这里的配置结构。
 */
#pragma once

#include "rm_control/common/result.h"
#include "rm_control/core/drag_teach_recorder.h"

#include <filesystem>
#include <iosfwd>

namespace rm_control::config {

/**
 * @brief 拖动示教录制程序的命令行解析结果。
 *
 * @reason 将危险的命令行授权与静态安全配置路径显式分离，确保入口层可以在连接前拒绝执行。
 *
 * @author 唐永康
 * @date 2026-07-10
 *
 * @details
 * 该结构体把“是否请求帮助”和“录制配置”放在一起返回给入口文件。
 * `record_config` 是 core 层真正需要的业务配置，CLI 层不会直接调用硬件。
 */
struct DragTeachRecordCliConfig {
    bool help_requested = false;                 ///< 是否请求帮助信息。
    bool live_requested = false;                 ///< 是否显式请求真实硬件模式。
    std::filesystem::path safety_config_path;    ///< 静态安全配置文件路径。
    core::DragTeachRecordConfig record_config;   ///< 拖动示教录制配置。
};

/**
 * @brief 打印拖动示教录制程序的命令行使用说明。
 *
 * @reason 集中维护安全选项说明，避免帮助文本与真实门控条件发生漂移。
 *
 * @author 唐永康
 * @date 2026-07-10
 *
 * @details
 * 该函数集中维护 usage 文本，避免 `main.cpp`、错误分支和测试中出现多份不一致文案。
 * 它不访问真实机械臂、不创建文件、不启动拖动示教。
 *
 * @param[in] program_name 当前进程名，可以为空指针。
 * @param[out] out 使用说明输出流。
 *
 * @return 无返回值。
 *
 * @calls 仅调用标准输出流，不访问配置文件或设备。
 * @safety 本函数不连接硬件、不触发运动。
 *
 * @throws 本函数不主动抛出异常；输出流异常由调用方处理。
 *
 * @note
 * 帮助文本必须强调拖动示教会访问真实硬件，后续维护时不能删除安全提示。
 *
 * @warning
 * 如果解析规则变化，必须同步更新此函数文本。
 *
 * @thread_safety
 * 函数本身无全局状态；并发写同一输出流需要调用方保护。
 *
 * @par 边界条件
 * `program_name == nullptr` 时使用默认程序名。
 *
 * @par 后续维护
 * 新增选项时应说明默认值和安全影响。
 */
void PrintDragTeachRecordUsage(const char *program_name, std::ostream &out);

/**
 * @brief 解析拖动示教录制程序的命令行参数。
 *
 * @reason 在任何连接动作前解析 `--live` 和安全配置路径，使错误参数保持 fail-closed。
 *
 * @author 唐永康
 * @date 2026-07-10
 *
 * @details
 * 该函数负责解析 `session_name`、录制时长、采样周期、存储根目录以及拖动示教模式选项。
 * 它只返回结构化配置，不连接 SDK、不移动机械臂，因此可以被单元测试直接覆盖。
 *
 * @param[in] argc 命令行参数数量。
 * @param[in] argv 命令行参数数组，允许元素为空指针。
 *
 * @return 成功时返回 `DragTeachRecordCliConfig`。
 * @return 失败时返回错误原因，例如未知选项、整数解析失败或位置参数过多。
 *
 * @calls 不调用厂商接口；只处理命令行文本。
 * @safety 未显式传入 `--live` 时 `live_requested` 永远为 false。
 *
 * @throws 本函数不主动抛出异常；所有解析失败通过 `Result` 返回。
 *
 * @note
 * - 默认 session name 使用时间戳生成。
 * - 默认存储目录来自 trajectory 模块。
 * - 默认启用厂商轨迹保存。
 *
 * @warning
 * 本函数不校验机械臂连接状态；真实硬件状态由 driver/core 层检查。
 *
 * @thread_safety
 * 函数只使用局部对象和只读输入，不依赖全局可变状态，线程安全。
 *
 * @par 边界条件
 * 空字符串、未知 `-` 开头选项、过多位置参数都会返回失败。
 *
 * @par 后续维护
 * 新增运动相关参数时必须保持“默认不绕过安全检查”的原则。
 */
common::Result<DragTeachRecordCliConfig> ParseDragTeachRecordCliArguments(int argc, char **argv);

} // namespace rm_control::config
