using System;

namespace MultiWheelC.TrajectoryPlanning.EMPlanner;

/// <summary>一次滚动周期的调用方冻结请求、身份和时钟值；构造后不读取外部状态。</summary>
public sealed class PlanningCycleInput
{
    /// <summary>从一次 EM 规划请求和调用方时刻创建周期输入。</summary>
    /// <param name="request">已冻结的 EM 请求；用于派生地图、路径、状态、上一轨迹和方向段身份。</param>
    /// <param name="now">调用方提供的当前 <see cref="DateTimeOffset"/>；用于周期调度，不由协调器替换。</param>
    public PlanningCycleInput(EmPlanningRequest request, DateTimeOffset now)
    {
        Request = request ?? throw new ArgumentNullException(nameof(request));
        Identity = PlanningCycleIdentity.FromRequest(request);
        Now = now;
        ReplanPeriodSeconds = ReadReplanPeriod(request.Configuration);
    }

    /// <summary>本周期消费的不可变 EM 规划请求快照。</summary>
    public EmPlanningRequest Request { get; }

    /// <summary>从 <see cref="Request"/> 派生的完整版本身份，用于拒绝过期发布。</summary>
    public PlanningCycleIdentity Identity { get; }

    /// <summary>调用方冻结的周期开始时刻。</summary>
    public DateTimeOffset Now { get; }

    /// <summary>从请求配置读取的重规划周期，单位 s；无效配置回退为 0.20 s。</summary>
    public double ReplanPeriodSeconds { get; }

    private static double ReadReplanPeriod(EmPlannerConfiguration configuration)
    {
        double configured = configuration?.Scheduling?.ReplanPeriodSeconds ?? 0.20d;
        return !double.IsNaN(configured) && !double.IsInfinity(configured) && configured > 0d ? configured : 0.20d;
    }
}
