using System;
using System.IO.Pipes;
using System.Security.AccessControl;
using System.Security.Principal;

namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Host.Ipc;

/// <summary>
///     Builds the <see cref="PipeSecurity"/> for the FOCAS Host pipe. Same pattern as
///     Galaxy.Host: only the configured OtOpcUa server principal SID gets
///     <c>ReadWrite | Synchronize</c>; LocalSystem + Administrators are explicitly denied
///     so a compromised service account on the same host can't escalate via the pipe.
/// </summary>
public static class PipeAcl
{
    public static PipeSecurity Create(SecurityIdentifier allowedSid)
    {
        if (allowedSid is null) throw new ArgumentNullException(nameof(allowedSid));

        var security = new PipeSecurity();

        security.AddAccessRule(new PipeAccessRule(
            allowedSid,
            PipeAccessRights.ReadWrite | PipeAccessRights.Synchronize,
            AccessControlType.Allow));

        var localSystem = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
        var admins      = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);

        if (allowedSid != localSystem)
            security.AddAccessRule(new PipeAccessRule(localSystem, PipeAccessRights.FullControl, AccessControlType.Deny));
        if (allowedSid != admins)
            security.AddAccessRule(new PipeAccessRule(admins,      PipeAccessRights.FullControl, AccessControlType.Deny));

        security.SetOwner(allowedSid);

        return security;
    }
}
