using Flyshot.Core.Domain;

namespace Flyshot.Runtime.Common;

/// <summary>
/// 定义控制器运行时的最小状态与执行契约，供兼容层在不关心底层 Socket 细节的情况下调度轨迹。
/// </summary>
public interface IControllerRuntime
{
    /// <summary>
    /// 重置当前机器人模型并清空控制器运行时状态。
    /// </summary>
    /// <param name="robot">当前机器人配置。</param>
    /// <param name="robotName">兼容层传入的机器人名称。</param>
    void ResetRobot(RobotProfile robot, string robotName);

    /// <summary>
    /// 选择当前活动控制器类型。
    /// </summary>
    /// <param name="sim">是否使用仿真控制器。</param>
    void SetActiveController(bool sim);

    /// <summary>
    /// 建立到控制器 IP 的连接。
    /// </summary>
    /// <param name="robotIp">控制器 IP。</param>
    void Connect(string robotIp);

    /// <summary>
    /// 断开当前控制器连接。
    /// </summary>
    void Disconnect();

    /// <summary>
    /// 使能机器人并记录底层缓冲区大小。
    /// </summary>
    /// <param name="bufferSize">运行时缓冲区大小。</param>
    void EnableRobot(int bufferSize);

    /// <summary>
    /// 关闭机器人使能。
    /// </summary>
    void DisableRobot();

    /// <summary>
    /// 停止当前运动。
    /// </summary>
    void StopMove();

    /// <summary>
    /// 获取当前速度倍率。
    /// </summary>
    /// <returns>速度倍率。</returns>
    double GetSpeedRatio();

    /// <summary>
    /// 设置当前速度倍率。
    /// </summary>
    /// <param name="ratio">目标速度倍率。</param>
    void SetSpeedRatio(double ratio);

    /// <summary>
    /// 获取当前 TCP 坐标。
    /// </summary>
    /// <returns>TCP 三维坐标。</returns>
    IReadOnlyList<double> GetTcp();

    /// <summary>
    /// 设置当前 TCP 坐标。
    /// </summary>
    /// <param name="x">TCP X。</param>
    /// <param name="y">TCP Y。</param>
    /// <param name="z">TCP Z。</param>
    void SetTcp(double x, double y, double z);

    /// <summary>
    /// 读取指定 IO 端口。
    /// </summary>
    /// <param name="port">IO 端口。</param>
    /// <param name="ioType">IO 类型。</param>
    /// <returns>IO 当前值。</returns>
    bool GetIo(int port, string ioType);

    /// <summary>
    /// 写入指定 IO 端口。
    /// </summary>
    /// <param name="port">IO 端口。</param>
    /// <param name="value">目标 IO 值。</param>
    /// <param name="ioType">IO 类型。</param>
    void SetIo(int port, bool value, string ioType);

    /// <summary>
    /// 获取当前关节位置。
    /// </summary>
    /// <returns>当前关节位置。</returns>
    IReadOnlyList<double> GetJointPositions();

    /// <summary>
    /// 获取当前末端位姿。
    /// </summary>
    /// <returns>当前末端位姿。</returns>
    IReadOnlyList<double> GetPose();

    /// <summary>
    /// 获取当前运行时状态快照。
    /// </summary>
    /// <returns>控制器状态快照。</returns>
    ControllerStateSnapshot GetSnapshot();

    /// <summary>
    /// 执行一条已经完成规划的轨迹，并更新最终关节位置。
    /// </summary>
    /// <param name="result">规划结果。</param>
    /// <param name="finalJointPositions">轨迹执行结束后的关节位置。</param>
    void ExecuteTrajectory(TrajectoryResult result, IReadOnlyList<double> finalJointPositions);

    /// <summary>
    /// 执行一条已经完成规划的直角坐标轨迹，并更新最终 TCP 位姿。
    /// </summary>
    /// <param name="result">规划结果，必须包含稠密直角坐标轨迹。</param>
    /// <param name="finalPose">轨迹执行结束后的 [x,y,z,w,p,r] 位姿。</param>
    void ExecuteCartesianTrajectory(TrajectoryResult result, IReadOnlyList<double> finalPose);
}
