import type { AuthzCatalog } from "./types.ts";

function union(values: string[]): string {
  if (!values.length) return "never";
  // JSON.stringify escapes backslashes, quotes, and control characters
  // (including raw newlines, which the registry does not reject in role
  // names and which would otherwise break out of the string literal).
  return values
    .slice()
    .sort()
    .map((value) => JSON.stringify(value))
    .join(" | ");
}

/**
 * Emit `Permission`/`Role` string-literal unions from the registered catalog.
 *
 * This does NOT make `can(ctx, "post:wrtie")` a type error — `can()`,
 * `guardPermission()`, and `decideFor()` all take a bare `string`, and
 * nothing in the framework consumes this generated file automatically.
 * Import the unions yourself to type your OWN helpers/constants, e.g.
 * `const PERM: Permission = "post:write"` or a typed wrapper around `can()`.
 */
export function generatePermissionTypes(catalog: AuthzCatalog): string {
  return `// Generated by \`wrnexus authz generate\`. DO NOT EDIT.

export type Permission = ${union([...catalog.permissions.keys()])};

export type Role = ${union([...catalog.roles.keys()])};
`;
}
