#pragma once

#include "rm_control/common/result.h"

#include <cstdint>
#include <filesystem>

namespace rm_control::config {

/**
 * @brief 拖动示教真实硬件执行所需的静态安全配置。
 *
 * @reason 将可审计的配置条件与命令行和运行时设备状态分离，避免单个输入源绕过安全门控。
 *
 * @author 唐永康
 * @date 2026-07-11
 *
 * @note 所有布尔开关默认关闭，O6 速度/转矩上限默认 0；人工确认和设备连接状态
 *       不允许从本结构伪造。
 */
struct DragTeachSafetyConfig {
    bool hardware_execution_enabled = false;
    bool emergency_stop_verified = false;
    bool safety_limits_loaded = false;
    bool workspace_and_virtual_wall_verified = false;
    bool native_replay_without_speed_control_accepted = false;
    bool trajectory_sample_period_confirmed = false;
    bool vendor_raw_units_per_degree_confirmed = false;
    int max_speed_percent = 10; // 1..100。
    int vendor_raw_units_per_degree = 1000;
    float maximum_origin_move_delta_deg = 30.0F;
    float max_joint_jump_deg = 5.0F;
    float max_joint_velocity_deg_per_second = 30.0F;
    float max_joint_acceleration_deg_per_second_squared = 100.0F;
    float maximum_absolute_force_newton = 100.0F;
    float maximum_absolute_torque_newton_meter = 20.0F;
    std::uint16_t maximum_o6_speed_command = 0U;
    std::uint16_t maximum_o6_torque_command = 0U;
};

/**
 * @brief 从 JSON 文件加载并校验拖动示教安全配置。
 *
 * @reason 真实硬件开关必须来自显式配置文件，并在连接设备前完成类型和值域校验。
 *
 * @author 唐永康
 * @date 2026-07-11
 *
 * @param config_path 安全配置文件路径；调用方保留所有权。
 * @return 成功时返回完整配置；文件、JSON、字段或数值非法时返回带路径上下文的失败。
 *
 * @calls rm_control::config::parseJson。
 * @safety 本函数不连接设备、不触发运动；失败时保持硬件执行禁用。
 * @note 配置缺少任一必填字段时拒绝加载，不使用隐式危险默认值。
 */
common::Result<DragTeachSafetyConfig>
LoadDragTeachSafetyConfig(const std::filesystem::path &config_path);

} // namespace rm_control::config
