/**
 * @file main.cpp
 * @brief RM JSON 指令运行器入口文件。
 *
 * @author mashiro
 * @date 2026-07-09
 * @last_modified 2026-07-09
 *
 * @details
 * 本文件是 `rm_json_runner` 可执行程序入口，只负责命令行参数解析结果处理、
 * JSON 文件加载、RealMan 驱动创建、核心 runner 装配和进程退出码返回。
 * 具体 JSON 解析、安全校验和硬件调用分别放在 config、core 和 drivers 层。
 *
 * 设计原则：
 * - `main()` 不包含业务控制逻辑；
 * - `--validate-only` 不连接 SDK、不访问真实机械臂；
 * - 真实硬件动作必须经过 JSON safety 配置和 `JsonCommandRunner` 校验；
 * - 所有失败路径返回明确退出码。
 *
 * @dependencies
 * - rm_control/config/json_command.h
 * - rm_control/config/json_runner_cli_config.h
 * - rm_control/core/json_command_runner.h
 * - rm_control/drivers/realman/realman_robot_arm.h
 */
#include "rm_control/config/json_command.h"
#include "rm_control/config/json_runner_cli_config.h"
#include "rm_control/core/json_command_runner.h"
#include "rm_control/drivers/realman/realman_robot_arm.h"

#include <iostream>

/**
 * @brief 启动 RM JSON 指令运行器。
 *
 * @author mashiro
 * @date 2026-07-09
 * @last_modified 2026-07-09
 *
 * @details
 * 该函数完成进程级调度：先解析 CLI 参数，再加载 JSON 指令文件；如果用户请求
 * `--validate-only`，函数在 JSON 结构校验成功后直接返回，不创建 RealMan 驱动。
 * 非 validate-only 模式下，函数创建 `RealManRobotArm` 并注入 `JsonCommandRunner`，
 * 由 core 层执行安全校验和命令调度。
 *
 * @param[in] argc 命令行参数数量。
 * @param[in] argv 命令行参数数组。
 *
 * @return 0 执行成功或帮助信息输出成功。
 * @return 1 CLI 参数错误或 JSON 文件加载失败。
 * @return 2 JSON 命令执行失败。
 * @return 64 命令行使用方式错误。
 *
 * @throws 本函数不主动抛出异常；底层模块通过 `Result` 返回错误。
 *
 * @note
 * `--validate-only` 只解析文件，不连接 SDK，因此适合作为新 JSON 文件的第一步验证。
 *
 * @warning
 * 非 validate-only 模式会连接真实 RM75；真实运动仍由 JSON safety 字段控制。
 *
 * @thread_safety
 * 入口函数按单进程主线程使用设计，不提供多线程重入保证。
 *
 * @par 边界条件
 * 参数数量错误、路径为空、JSON 文件不存在或格式错误都会在连接硬件前失败。
 *
 * @par 后续维护
 * 新增启动参数时应修改 CLI 配置模块，不应把解析逻辑写回本函数。
 */
int main(int argc, char **argv) {
    const auto cli_config = rm_control::config::ParseJsonRunnerCliArguments(argc, argv);
    if (!cli_config.ok) {
        std::cerr << "Invalid arguments: " << cli_config.error_message << '\n';
        rm_control::config::PrintJsonRunnerUsage(argv == nullptr ? nullptr : argv[0], std::cerr);
        return 64;
    }
    if (cli_config.value.help_requested) {
        rm_control::config::PrintJsonRunnerUsage(argv == nullptr ? nullptr : argv[0], std::cout);
        return 0;
    }

    const auto program = rm_control::config::loadCommandProgramFromFile(
        cli_config.value.command_file_path);
    if (!program.ok) {
        std::cerr << "Failed to load JSON command file: " << program.error_message << '\n';
        return 1;
    }

    std::cout << "JSON command file parsed successfully. command_count="
              << program.value.commands.size() << '\n';

    if (cli_config.value.validate_only) {
        std::cout << "validate-only mode: no SDK connection or command execution.\n";
        return 0;
    }

    rm_control::drivers::realman::RealManRobotArm robot;
    rm_control::core::JsonCommandRunner runner(robot);
    const auto result = runner.run(program.value, std::cout);
    if (!result.ok) {
        std::cerr << "Command execution failed: " << result.error_message << '\n';
        return 2;
    }

    std::cout << "\nAll JSON commands finished.\n";
    return 0;
}
