// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.Text.Json;
namespace autoShell.Handlers;
///
/// Base class for all action handlers. Co-registers action names and handler functions
/// via or , providing automatic
/// and dictionary-based dispatch.
/// Subclasses register actions in their constructor.
///
internal abstract class ActionHandlerBase : IActionHandler
{
private static readonly JsonSerializerOptions CamelCaseOptions = new()
{
PropertyNameCaseInsensitive = true
};
private readonly Dictionary> _actions = new(StringComparer.OrdinalIgnoreCase);
///
public IEnumerable SupportedActions => _actions.Keys;
///
/// Registers an action name and its handler function. Throws if the name is already registered.
///
protected void AddAction(string actionName, Func handler)
{
if (!_actions.TryAdd(actionName, handler))
{
throw new InvalidOperationException(
$"Action '{actionName}' is already registered in {GetType().Name}.");
}
}
///
/// Registers an action with a strongly-typed parameter record.
/// The is automatically deserialized to .
///
protected void AddAction(string actionName, Func handler)
{
AddAction(actionName, parameters =>
{
T typed;
try
{
if (parameters.ValueKind is JsonValueKind.Undefined or JsonValueKind.Null)
{
return ActionResult.Fail($"Invalid parameters for '{actionName}': parameters are missing or null");
}
typed = JsonSerializer.Deserialize(parameters.GetRawText(), CamelCaseOptions);
}
catch (JsonException ex)
{
return ActionResult.Fail($"Invalid parameters for '{actionName}': {ex.Message}");
}
return typed == null
? ActionResult.Fail($"Invalid parameters for '{actionName}': null parameters not allowed")
: handler(typed);
});
}
///
public virtual ActionResult Handle(string key, JsonElement parameters)
{
return _actions.TryGetValue(key, out var handler)
? handler(parameters)
: ActionResult.Fail($"Unknown action: {key}");
}
}