using System;

namespace MultiWheelC.TrajectoryPlanning.EMPlanner;

/// <summary>一次滚动规划周期的不可变完成记录，区分规划结果与是否获准发布。</summary>
public sealed class PlanningCycleResult
{
    /// <summary>创建周期完成记录。</summary>
    /// <param name="version">协调器分配的正数单调周期版本。</param>
    /// <param name="identity">本周期绑定的地图、路径、状态、上一轨迹和方向段身份。</param>
    /// <param name="result">纯规划服务返回的结果，可能为 Superseded、取消或失败。</param>
    /// <param name="published">仅当完整成功轨迹仍为当前身份时为 <see langword="true"/>。</param>
    /// <param name="diagnostic">附加的周期或观察器诊断文本。</param>
    public PlanningCycleResult(long version, PlanningCycleIdentity identity, EmPlanningResult result, bool published,
        string diagnostic)
    {
        if (version <= 0)
            throw new ArgumentOutOfRangeException(nameof(version));
        Version = version;
        Identity = identity ?? throw new ArgumentNullException(nameof(identity));
        Result = result ?? throw new ArgumentNullException(nameof(result));
        Published = published;
        Diagnostic = diagnostic ?? string.Empty;
    }

    /// <summary>本周期的单调递增版本号。</summary>
    public long Version { get; }

    /// <summary>决定该结果是否仍可发布的完整不可变身份。</summary>
    public PlanningCycleIdentity Identity { get; }

    /// <summary>纯 EM 规划结果；失败结果不携带可执行轨迹。</summary>
    public EmPlanningResult Result { get; }

    /// <summary>该结果是否已原子替换协调器的已发布轨迹。</summary>
    public bool Published { get; }

    /// <summary>周期处理或可选观察器产生的诊断文本。</summary>
    public string Diagnostic { get; }

    internal PlanningCycleResult WithDiagnostic(string diagnostic)
    {
        return new PlanningCycleResult(Version, Identity, Result, Published, diagnostic);
    }
}
