using System.Text.Json.Serialization;

namespace Flyshot.Core.Domain;

/// <summary>
/// Represents a request to plan or execute a flyshot trajectory.
/// </summary>
public sealed class TrajectoryRequest
{
    /// <summary>
    /// Initializes a trajectory request with compatibility-oriented defaults.
    /// </summary>
    public TrajectoryRequest(
        RobotProfile robot,
        FlyshotProgram program,
        PlanningMethod method,
        bool moveToStart = false,
        bool saveTrajectoryArtifacts = false,
        bool useCache = false)
    {
        Robot = robot ?? throw new ArgumentNullException(nameof(robot));
        Program = program ?? throw new ArgumentNullException(nameof(program));
        Method = method;
        MoveToStart = moveToStart;
        SaveTrajectoryArtifacts = saveTrajectoryArtifacts;
        UseCache = useCache;
    }

    /// <summary>
    /// Gets the robot profile that constrains planning and runtime compatibility.
    /// </summary>
    [JsonPropertyName("robot")]
    public RobotProfile Robot { get; }

    /// <summary>
    /// Gets the uploaded program to be planned or executed.
    /// </summary>
    [JsonPropertyName("program")]
    public FlyshotProgram Program { get; }

    /// <summary>
    /// Gets the selected planning method.
    /// </summary>
    [JsonPropertyName("method")]
    public PlanningMethod Method { get; }

    /// <summary>
    /// Gets a value indicating whether the robot should move to the first waypoint before execution.
    /// </summary>
    [JsonPropertyName("moveToStart")]
    public bool MoveToStart { get; }

    /// <summary>
    /// Gets a value indicating whether trajectory artifacts should be exported.
    /// </summary>
    [JsonPropertyName("saveTrajectoryArtifacts")]
    public bool SaveTrajectoryArtifacts { get; }

    /// <summary>
    /// Gets a value indicating whether cached planning artifacts may be reused.
    /// </summary>
    [JsonPropertyName("useCache")]
    public bool UseCache { get; }
}

/// <summary>
/// Identifies the planning mode requested by compatibility APIs.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum PlanningMethod
{
    /// <summary>
    /// Uses the cubic-spline ICSP planner.
    /// </summary>
    Icsp,

    /// <summary>
    /// Uses the adaptive ICSP planner that may insert additional points.
    /// </summary>
    SelfAdaptIcsp,

    /// <summary>
    /// Uses the Double-S planner.
    /// </summary>
    Doubles
}
