using System; using MxGateway.Contracts.Proto; using MxGateway.Worker.Conversion; using MxGateway.Worker.Sta; namespace MxGateway.Worker.MxAccess; public sealed class MxAccessCommandExecutor : IStaCommandExecutor { private readonly MxAccessSession session; private readonly VariantConverter variantConverter; public MxAccessCommandExecutor(MxAccessSession session) : this(session, new VariantConverter()) { } public MxAccessCommandExecutor( MxAccessSession session, VariantConverter variantConverter) { this.session = session ?? throw new ArgumentNullException(nameof(session)); this.variantConverter = variantConverter ?? throw new ArgumentNullException(nameof(variantConverter)); } public MxCommandReply Execute(StaCommand command) { if (command is null) { throw new ArgumentNullException(nameof(command)); } return command.Kind switch { MxCommandKind.Register => ExecuteRegister(command), MxCommandKind.Unregister => ExecuteUnregister(command), _ => CreateInvalidRequestReply(command, $"Unsupported MXAccess command kind {command.Kind}."), }; } private MxCommandReply ExecuteRegister(StaCommand command) { if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.Register) { return CreateInvalidRequestReply(command, "Register command payload is required."); } int serverHandle = session.Register(command.Command.Register.ClientName); MxCommandReply reply = CreateOkReply(command); reply.ReturnValue = variantConverter.Convert(serverHandle); reply.Register = new RegisterReply { ServerHandle = serverHandle, }; return reply; } private MxCommandReply ExecuteUnregister(StaCommand command) { if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.Unregister) { return CreateInvalidRequestReply(command, "Unregister command payload is required."); } session.Unregister(command.Command.Unregister.ServerHandle); return CreateOkReply(command); } private static MxCommandReply CreateOkReply(StaCommand command) { return new MxCommandReply { SessionId = command.SessionId, CorrelationId = command.CorrelationId, Kind = command.Kind, Hresult = 0, ProtocolStatus = new ProtocolStatus { Code = ProtocolStatusCode.Ok, Message = "OK", }, }; } private static MxCommandReply CreateInvalidRequestReply( StaCommand command, string message) { return new MxCommandReply { SessionId = command.SessionId, CorrelationId = command.CorrelationId, Kind = command.Kind, ProtocolStatus = new ProtocolStatus { Code = ProtocolStatusCode.InvalidRequest, Message = message, }, DiagnosticMessage = message, }; } }