import type { Rule, Ruleset } from "./rule";
import type { FlatPermissionConfig } from "./types";
import { isDenyWithReason, isPermissionState } from "./types";

/**
 * Convert a flat permission config into a Ruleset.
 *
 * Each key is a surface name. A string value is shorthand for
 * `{ "*": action }`. An object value maps patterns to actions.
 * A pattern value may be a PermissionState string or a `DenyWithReason`
 * object (`{ action: "deny", reason?: string }`).
 * Invalid action values are silently skipped.
 *
 * The universal fallback key `"*"` is included if present — callers
 * that use `"*"` only for `synthesizeDefaults()` should strip it before
 * calling this function.
 */
export function normalizeFlatConfig(permission: FlatPermissionConfig): Ruleset {
  const rules: Rule[] = [];
  for (const [surface, value] of Object.entries(permission)) {
    if (typeof value === "string") {
      if (isPermissionState(value)) {
        rules.push({ surface, pattern: "*", action: value, origin: "builtin" });
      }
      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- defensive null check; value type does not include null but runtime JSON may
    } else if (typeof value === "object" && value !== null) {
      for (const [pattern, action] of Object.entries(value)) {
        if (isDenyWithReason(action)) {
          rules.push({
            surface,
            pattern,
            action: "deny",
            reason: action.reason,
            origin: "builtin",
          });
        } else if (isPermissionState(action)) {
          rules.push({ surface, pattern, action, origin: "builtin" });
        }
      }
    }
  }
  return rules;
}
