using System;


namespace AIRuntime.Runtime.Capabilities.Permissions
{
    /// <summary>
    /// Raised when a capability cannot execute because
    /// of the active permission or approval policy.
    /// </summary>
    public sealed class CapabilityPermissionException :
        InvalidOperationException
    {
        public string CapabilityName
        {
            get;
        }


        public CapabilityPermission Permission
        {
            get;
        }


        public CapabilityPermissionDecision Decision
        {
            get;
        }


        public CapabilityPermissionException(
            string capabilityName,
            CapabilityPermission permission,
            CapabilityPermissionDecision decision,
            string message)
            : base(message)
        {
            CapabilityName =
                capabilityName ??
                string.Empty;


            Permission =
                permission;


            Decision =
                decision;
        }


        public static CapabilityPermissionException CreateDenied(
            string capabilityName,
            CapabilityPermission permission)
        {
            return new CapabilityPermissionException(
                capabilityName,
                permission,
                CapabilityPermissionDecision.Deny,
                $"Capability '{capabilityName}' was denied because " +
                $"permission '{permission}' is not allowed.");
        }


        public static CapabilityPermissionException CreateApprovalRequired(
            string capabilityName,
            CapabilityPermission permission)
        {
            return new CapabilityPermissionException(
                capabilityName,
                permission,
                CapabilityPermissionDecision.RequireApproval,
                $"Capability '{capabilityName}' requires approval for " +
                $"permission '{permission}', but no approval handler is configured.");
        }


        public static CapabilityPermissionException CreateRejected(
            string capabilityName,
            CapabilityPermission permission,
            string reason)
        {
            string message =
                $"Capability '{capabilityName}' was rejected during approval.";


            if (!string.IsNullOrWhiteSpace(reason))
            {
                message +=
                    $" Reason: {reason}";
            }


            return new CapabilityPermissionException(
                capabilityName,
                permission,
                CapabilityPermissionDecision.RequireApproval,
                message);
        }
    }
}