using ZB.MOM.WW.ScadaBridge.CentralUI.Auth;
using System.Security.Claims;
using Akka.Actor;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.Logging;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.ManagementService;
using ZB.MOM.WW.ScadaBridge.Security;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Services;
///
/// Default implementation — a thin facade that
/// dispatches the to the central
/// ManagementActor through the in-process
/// (the same Ask seam the HTTP /management endpoint uses). The actor authorizes
/// the command against the supplied (Designer-gated) and
/// runs every move guard server-side — the target site must exist, the target must not
/// already own a same-named connection, no instance binding may reference the
/// connection, and no name-based native-alarm-source reference may be orphaned. None of
/// that is re-implemented here; a guard failure returns as a classified error.
///
///
/// Mirrors : the current Blazor principal is projected
/// to an so the server's role gate runs against the real
/// identity, and the three management response shapes plus any transport fault collapse
/// into a typed .
///
public sealed class DataConnectionMoveService : IDataConnectionMoveService
{
private static readonly TimeSpan AskTimeout = TimeSpan.FromSeconds(30);
private readonly ManagementActorHolder _holder;
private readonly AuthenticationStateProvider _auth;
private readonly ILogger _logger;
///
/// Initializes a new instance of the .
///
/// Holder for the central ManagementActor reference.
/// Authentication state provider used to project the current principal.
/// Logger instance.
public DataConnectionMoveService(
ManagementActorHolder holder,
AuthenticationStateProvider auth,
ILogger logger)
{
_holder = holder ?? throw new ArgumentNullException(nameof(holder));
_auth = auth ?? throw new ArgumentNullException(nameof(auth));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
///
public async Task MoveAsync(
int connectionId, int targetSiteId, CancellationToken cancellationToken = default)
{
var response = await SendAsync(
new MoveDataConnectionCommand(connectionId, targetSiteId), cancellationToken);
return response switch
{
ManagementSuccess => DataConnectionMoveResult.Ok(),
ManagementUnauthorized unauthorized => DataConnectionMoveResult.Fail(unauthorized.Message),
ManagementError error => DataConnectionMoveResult.Fail(error.Error),
_ => DataConnectionMoveResult.Fail(DescribeFailure(response)),
};
}
///
/// Wraps in a for the
/// current principal and Asks the ManagementActor. Transport faults (timeout,
/// actor not yet started, cancellation→propagated) become a synthetic
/// so callers handle one response shape.
///
private async Task