using System.Runtime.CompilerServices;
using ZB.MOM.WW.MxGateway.Contracts.Proto;
using ZB.MOM.WW.MxGateway.Server.Alarms;

namespace ZB.MOM.WW.MxGateway.Tests.TestSupport;

/// <summary>
///     <see cref="IGatewayAlarmService"/> test double — serves a scripted
///     active-alarm set and acknowledges every request with an OK status,
///     so gRPC service tests can exercise the alarm handlers without the
///     real gateway alarm monitor or a worker.
/// </summary>
public sealed class FakeGatewayAlarmService : IGatewayAlarmService
{
    /// <inheritdoc />
    public GatewayAlarmMonitorState State { get; set; } = GatewayAlarmMonitorState.Monitoring;

    /// <inheritdoc />
    public string? LastError { get; set; }

    /// <inheritdoc />
    public int? WorkerProcessId { get; set; }

    /// <inheritdoc />
    public IReadOnlyList<ActiveAlarmSnapshot> CurrentAlarms { get; set; } = [];

    /// <inheritdoc />
    public bool SnapshotTruncated { get; set; }

    /// <inheritdoc />
    public async IAsyncEnumerable<AlarmFeedMessage> StreamAsync(
        string? alarmFilterPrefix,
        [EnumeratorCancellation] CancellationToken cancellationToken)
    {
        foreach (ActiveAlarmSnapshot alarm in CurrentAlarms)
        {
            cancellationToken.ThrowIfCancellationRequested();
            yield return new AlarmFeedMessage { ActiveAlarm = alarm };
        }

        yield return new AlarmFeedMessage { SnapshotComplete = true };
        await Task.CompletedTask.ConfigureAwait(false);
    }

    /// <inheritdoc />
    public Task<AcknowledgeAlarmReply> AcknowledgeAsync(
        AcknowledgeAlarmRequest request,
        CancellationToken cancellationToken)
    {
        return Task.FromResult(new AcknowledgeAlarmReply
        {
            CorrelationId = request.ClientCorrelationId,
            ProtocolStatus = new ProtocolStatus { Code = ProtocolStatusCode.Ok },
            DiagnosticMessage = string.Empty,
        });
    }
}
