using ZB.MOM.WW.GalaxyRepository.Grpc;
using ZB.MOM.WW.MxGateway.Contracts.Proto;

namespace ZB.MOM.WW.MxGateway.Server.Security.Authorization;

public sealed class GatewayGrpcScopeResolver
{
    /// <summary>
    /// Resolves the required authorization scope for a gRPC request.
    /// </summary>
    /// <param name="request">The gRPC request.</param>
    /// <returns>Required authorization scope.</returns>
    public string ResolveRequiredScope(object request)
    {
        return request switch
        {
            OpenSessionRequest => GatewayScopes.SessionOpen,
            CloseSessionRequest => GatewayScopes.SessionClose,
            StreamEventsRequest => GatewayScopes.EventsRead,
            MxCommandRequest commandRequest => ResolveCommandScope(commandRequest.Command?.Kind ?? MxCommandKind.Unspecified),
            AcknowledgeAlarmRequest => GatewayScopes.InvokeWrite,
            StreamAlarmsRequest => GatewayScopes.EventsRead,
            QueryActiveAlarmsRequest => GatewayScopes.EventsRead,
            TestConnectionRequest or
            GetLastDeployTimeRequest or
            DiscoverHierarchyRequest or
            WatchDeployEventsRequest or
            BrowseChildrenRequest => GatewayScopes.MetadataRead,
            _ => GatewayScopes.Admin
        };
    }

    private static string ResolveCommandScope(MxCommandKind kind)
    {
        return kind switch
        {
            MxCommandKind.Write or
            MxCommandKind.Write2 or
            MxCommandKind.WriteBulk or
            MxCommandKind.Write2Bulk => GatewayScopes.InvokeWrite,

            MxCommandKind.WriteSecured or
            MxCommandKind.WriteSecured2 or
            MxCommandKind.WriteSecuredBulk or
            MxCommandKind.WriteSecured2Bulk or
            MxCommandKind.AuthenticateUser => GatewayScopes.InvokeSecure,

            MxCommandKind.ArchestraUserToId or
            MxCommandKind.GetSessionState or
            MxCommandKind.GetWorkerInfo => GatewayScopes.MetadataRead,

            MxCommandKind.DrainEvents => GatewayScopes.EventsRead,
            MxCommandKind.ShutdownWorker => GatewayScopes.Admin,

            _ => GatewayScopes.InvokeRead
        };
    }
}
