// Copyright (c) Microsoft. All rights reserved.
using System.Text.RegularExpressions;
namespace AGUIDojoClient.Components.Demos.HumanInTheLoop;
///
/// Applies JSON Patch operations to a Plan.
/// Uses hardcoded path parsing for the expected paths:
/// - /steps/{index}/status
/// - /steps/{index}/description
///
public static partial class PlanPatcher
{
// Regex to match paths like /steps/0/status or /steps/1/description
[GeneratedRegex(@"^/steps/(\d+)/(status|description)$")]
private static partial Regex StepPropertyPathRegex();
///
/// Applies a JSON Patch operation to the plan.
/// Only supports "replace" operations on /steps/{index}/status and /steps/{index}/description paths.
///
/// The plan to modify.
/// The patch operation to apply.
/// True if the operation was applied successfully, false otherwise.
public static bool ApplyPatch(Plan plan, JsonPatchOperation operation)
{
ArgumentNullException.ThrowIfNull(plan);
ArgumentNullException.ThrowIfNull(operation);
// Only support "replace" operations
if (!string.Equals(operation.Op, "replace", StringComparison.OrdinalIgnoreCase))
{
return false;
}
var match = StepPropertyPathRegex().Match(operation.Path);
if (!match.Success)
{
return false;
}
if (!int.TryParse(match.Groups[1].Value, out int stepIndex))
{
return false;
}
if (stepIndex < 0 || stepIndex >= plan.Steps.Count)
{
return false;
}
var propertyName = match.Groups[2].Value;
var step = plan.Steps[stepIndex];
switch (propertyName.ToUpperInvariant())
{
case "STATUS":
step.Status = operation.Value?.ToString() ?? "pending";
return true;
case "DESCRIPTION":
step.Description = operation.Value?.ToString() ?? string.Empty;
return true;
default:
return false;
}
}
///
/// Applies multiple JSON Patch operations to the plan.
///
/// The plan to modify.
/// The patch operations to apply.
/// The number of operations successfully applied.
public static int ApplyPatches(Plan plan, IEnumerable operations)
{
int appliedCount = 0;
foreach (var operation in operations)
{
if (ApplyPatch(plan, operation))
{
appliedCount++;
}
}
return appliedCount;
}
}