import { z } from 'zod';

/**
 * POSIX-style absolute path. Must start with `/`, max 4096 chars, no NULs,
 * no CR/LF/DEL, no backslashes (Windows-style rejected). Further policy
 * (root-scope, traversal hardening) applied by `validatePath` server-side.
 */
export const PathSchema = z
  .string()
  .min(1)
  .max(4096)
  .regex(/^\//, 'must be absolute (start with /)')
  .refine((s) => !/[\x00-\x08\x0a-\x1f\x7f\\]/.test(s), {
    message: 'contains forbidden control or backslash characters',
  });

export type Path = z.infer<typeof PathSchema>;

/** Base64url(16 bytes) — used for both requestId and idempotencyKey. */
export const RequestIdSchema = z
  .string()
  .min(22)
  .max(22)
  .regex(/^[A-Za-z0-9_-]+$/, 'invalid base64url');

export type RequestId = z.infer<typeof RequestIdSchema>;

export const IdempotencyKeySchema = RequestIdSchema;
export type IdempotencyKey = z.infer<typeof IdempotencyKeySchema>;

/**
 * Opaque cursor token. Server-defined shape; clients pass through verbatim.
 * Capped at 2 KiB to prevent over-sized cursors leaking server state.
 */
export const CursorSchema = z.string().min(1).max(2048);
export type Cursor = z.infer<typeof CursorSchema>;

/** Hex-encoded SHA-256 (64 chars). */
export const Sha256HexSchema = z.string().length(64).regex(/^[0-9a-f]+$/);

/** Standard base64 (with padding) used for binary blobs in JSON envelopes. */
export const Base64Schema = z.string().regex(/^[A-Za-z0-9+/]*=*$/);
