import { hasAllFeatures as matchesAllFeatures } from "./features.js";
import {
  filterGrantsByEnabledModules,
  getConcreteFeatureIds,
  getEnabledModuleIds,
  getOwningModuleId,
  hasEnabledModulesRegistry
} from "./enabledModulesRegistry.js";
import { composeAclFeatureOverrides } from "../modules/overrides.js";
function getRemovedAclFeatureIds() {
  return Object.entries(composeAclFeatureOverrides()).filter(([, override]) => override === null).map(([featureId]) => featureId);
}
function isAclFeatureRemoved(featureId) {
  return composeAclFeatureOverrides()[featureId] === null;
}
function isFeatureEnabled(featureId) {
  if (!hasEnabledModulesRegistry()) return true;
  const enabledModuleIds = getEnabledModuleIds();
  return enabledModuleIds.includes(getOwningModuleId(featureId));
}
function authorizeFeatures(required, subject) {
  if (required.length === 0) return true;
  if (subject.scopeAllowed === false) return false;
  if (required.some((featureId) => isAclFeatureRemoved(featureId) || !isFeatureEnabled(featureId))) {
    return false;
  }
  if (subject.unrestricted === true) return true;
  return matchesAllFeatures(
    filterGrantsByEnabledModules(subject.grantedFeatures),
    required
  );
}
function resolveEffectiveFeatures(grantedFeatures) {
  const filteredGrants = filterGrantsByEnabledModules(grantedFeatures).filter((featureId) => !isAclFeatureRemoved(featureId));
  if (!hasEnabledModulesRegistry()) {
    return filteredGrants.filter((featureId, index, features) => featureId !== "*" && !featureId.endsWith(".*") && features.indexOf(featureId) === index);
  }
  const result = [];
  const seen = /* @__PURE__ */ new Set();
  const addFeature = (featureId) => {
    if (seen.has(featureId) || isAclFeatureRemoved(featureId) || !isFeatureEnabled(featureId)) {
      return;
    }
    seen.add(featureId);
    result.push(featureId);
  };
  for (const featureId of getConcreteFeatureIds()) {
    if (matchesAllFeatures(filteredGrants, [featureId])) addFeature(featureId);
  }
  for (const featureId of filteredGrants) {
    if (featureId === "*" || featureId.endsWith(".*")) continue;
    addFeature(featureId);
  }
  return result;
}
export {
  authorizeFeatures,
  getRemovedAclFeatureIds,
  isAclFeatureRemoved,
  resolveEffectiveFeatures
};
//# sourceMappingURL=featurePolicy.js.map
