#pragma once

#include "rm_control/common/result.h"
#include "rm_control/interfaces/tool_modbus_bus.h"

#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

namespace rm_control::core {

struct O6BusScanConfig {
    std::vector<std::uint8_t> device_ids{0x27U, 0x28U};
    std::uint16_t identity_start_address = 30U;
    std::size_t identity_register_count = 6U;
};

struct O6BusScanResponse {
    std::uint8_t device_id = 0U;
    bool multiple_read_succeeded = false;
    std::vector<std::uint16_t> identity_registers;
    std::string multiple_read_error;
    bool single_read_succeeded = false;
    std::uint16_t single_freedom_register = 0U;
    std::string single_read_error;
    bool single_and_multiple_reads_match = false;
    bool matches_o6_identity_shape = false;
};

struct O6BusScanReport {
    std::size_t attempted_device_count = 0U;
    std::size_t failed_device_count = 0U;
    std::size_t confirmed_o6_device_count = 0U;
    std::vector<O6BusScanResponse> responses;
};

/**
 * @brief 对 O6 默认左右手地址执行目标化只读身份探测。
 * @reason 固定探测 0x27/0x28 的 FC04 地址 30..35，并用单寄存器地址 30 交叉验证
 *         RM_API2 的两条读取路径，避免无边界全地址扫描。
 * @author 唐永康
 * @date 2026-07-11
 * @param tool_bus 已连接并显式初始化的工具端 Modbus 主站。
 * @param config 固定候选设备和身份寄存器范围；偏离 O6 默认值会被拒绝。
 * @return 参数有效时返回两个设备的双路径结果和原始错误上下文。
 * @calls IToolModbusBus::ReadInputRegisters 和 ReadInputRegister。
 * @safety 只调用功能码 04，不写保持寄存器，不触发 O6 或机械臂动作。
 * @note 每条读取路径仅调用一次，不自动重试。
 */
common::Result<O6BusScanReport> ScanO6IdentityRegisters(
    interfaces::IToolModbusBus &tool_bus,
    const O6BusScanConfig &config);

} // namespace rm_control::core
