import { RenamableEntityType } from '@openhi/workflows';

/**
 * Enumerate projection rows affected by a Tenant / User / Role rename
 * for the TR-023 rename cascade.
 *
 * One page per call; the cascade state machine outer loop walks the
 * returned `cursors` map back into this operation until every per-entity
 * stream returns `null`. Each emitted row carries:
 *
 * - the projection-entity name (so the rewrite-chunk operation can map
 *   it to the correct ElectroDB entity in `executeMultiWrite`),
 * - the **existing** composite key (used for the `delete` triple in the
 *   transact-write pair),
 * - the **new** composite key (used for the `put` triple — same row
 *   identity but a rewritten SK when the SK encodes the renamed
 *   normalized name), and
 * - the row's existing attributes (carried verbatim into the `put` so
 *   `summary`, `vid`, `lastUpdated`, etc. are preserved across the
 *   rewrite), with the renamed `denormalized<CarrierEntity>Name`
 *   replaced by the new display name.
 *
 * Per-entityType query plan (per the ADR-018 implementation guide § 5):
 *
 * - **User rename**: under `PK = USER#ID#<userId>` — Membership user-
 *   projection rows (patterns #3 + #4) and RoleAssignment user-projection
 *   rows (pattern #5). Workspace-side projection rows
 *   (membershipWorkspaceProjection #2 + roleAssignmentWorkspaceProjection
 *   #9) encode `<normalizedUserName>` in their SK; this operation
 *   discovers the affected workspaces from the user's pattern-#4
 *   memberships and queries each workspace partition for them.
 * - **Role rename**: under every affected user partition — RoleAssignment
 *   user-projection rows (pattern #5) sort on `<normalizedRoleName>` and
 *   need a SK rewrite. RoleAssignment canonical (pattern #8) and
 *   workspace-projection (pattern #9) sort on raw `<roleId>` so only the
 *   denormalized attr changes (no SK rewrite). The affected user-ids
 *   are discovered via the canonical RoleAssignment GSI1 (`<roleId>#`
 *   prefix).
 * - **Tenant rename**: only `denormalizedTenantName` updates — SKs do
 *   not carry tenant-name; the row identity is preserved. Affected user-
 *   ids are discovered via the canonical Membership GSI1 page.
 *
 * For #1023 the User-rename path is implemented in full; the Tenant /
 * Role discovery hooks are scaffolded with the right query shape and
 * cursor map but only walk one canonical discovery batch per call (the
 * cascade outer loop pages through them). See § 5 of the implementation
 * guide for the full matrix.
 *
 * @see .state/adr-018-implementation-guide.md § 5 (TR-023 Rename-Cascade Consumer Contract)
 * @see .claude/rules/data-layer-layout.md
 */

/**
 * Projection-entity name keys this operation may emit. Each key maps to
 * an entity in the control-plane service; the rewrite-chunk consumer
 * forwards it to `executeMultiWrite` as the `entity` field on a triple.
 */
declare const RENAME_CASCADE_PROJECTION_ENTITY: {
    readonly MembershipUserProjection: "membershipUserProjection";
    readonly MembershipWorkspaceProjection: "membershipWorkspaceProjection";
    readonly RoleAssignmentUserProjection: "roleAssignmentUserProjection";
    readonly RoleAssignmentWorkspaceProjection: "roleAssignmentWorkspaceProjection";
};
type RenameCascadeProjectionEntity = (typeof RENAME_CASCADE_PROJECTION_ENTITY)[keyof typeof RENAME_CASCADE_PROJECTION_ENTITY];
/**
 * One row to rewrite — the cascade rewrite-chunk operation turns each
 * entry into a `delete oldKey` + `put newPayload` transact-write pair.
 *
 * `oldKey` and `newKey` differ only in the SK segment when the SK
 * encodes a normalized form of the renamed name. For Tenant rename and
 * for SK-stable RoleAssignment projections (canonical pattern #8 and
 * workspace pattern #9 under a Role rename), `oldKey === newKey` and
 * the rewrite collapses to a single `put` overwrite.
 */
interface RenameCascadeRewriteTarget {
    readonly entity: RenameCascadeProjectionEntity;
    /** Composite key payload for the existing row. */
    readonly oldKey: Record<string, string>;
    /** Composite key payload for the rewritten row. */
    readonly newKey: Record<string, string>;
    /**
     * Full row payload to write at `newKey` — carries the existing
     * `summary`, `vid`, `lastUpdated`, and discriminating fields, with
     * the renamed `denormalized<CarrierEntity>Name` swapped to the new
     * display name.
     */
    readonly newItem: Record<string, unknown>;
    /**
     * `true` when `oldKey` and `newKey` differ — the rewrite must atomic
     * delete the old row and put the new row in the same transaction.
     * `false` when only the denormalized attr changes — a single `put`
     * overwrite is sufficient.
     */
    readonly skRewriteRequired: boolean;
}

/**
 * Shared event-shape constants for the TR-023 rename-cascade consumer.
 * The cascade's input detail-type (on the data event bus) and its two
 * terminal detail-types (on the ops event bus) are owned by
 * `@openhi/workflows`; this module re-imports them so the workflow
 * construct can wire the EventBridge rule and the terminal publisher
 * from a single place.
 *
 * @see .state/adr-018-implementation-guide.md section 5
 */

/**
 * Stable logical name registered with the shared `WorkflowDedupTable`
 * (TR-015). The state machine's `DedupCheck` state writes a row keyed
 * by `(consumerName, eventId, attempt)` to absorb EventBridge retries.
 */
declare const RENAME_CASCADE_CONSUMER_NAME: "rename-cascade";
/**
 * Distributed-Map max concurrency. Per the ADR-018 implementation guide
 * section 5: Distributed Map (NOT inline — TR-022 owning-delete uses
 * inline), tunable via the construct's `cascadeMapConcurrency` prop.
 * Operators may scale this down on first rollout.
 */
declare const RENAME_CASCADE_DEFAULT_CONCURRENCY: 10;
/**
 * `CascadeFailed` alarm threshold — fires when ExecutionsFailed exceeds
 * the value over the configured period. Per the implementation guide
 * section 5 "Alarm thresholds" table.
 */
declare const RENAME_CASCADE_FAILED_THRESHOLD: 0;
/**
 * `CascadeSlow` alarm threshold (in seconds) — fires when ExecutionTime
 * p99 exceeds the value. Per the implementation guide section 5.
 */
declare const RENAME_CASCADE_SLOW_THRESHOLD_SECONDS: 300;
/**
 * Inputs the cascade list-targets step receives. Most fields come
 * straight off the `ControlPlaneRenameV1` envelope payload; `cursors`
 * threads through the outer loop.
 */
interface RenameCascadeListInput {
    readonly entityType: RenamableEntityType;
    readonly entityId: string;
    readonly tenantId?: string;
    readonly oldName: string;
    readonly newName: string;
    readonly oldNormalizedName: string;
    readonly newNormalizedName: string;
    readonly cursors?: Record<string, string | null>;
    /** Cumulative `itemsRewritten` carried forward across pages. */
    readonly itemsRewritten?: number;
    /** Cumulative `chunkCount` carried forward across pages. */
    readonly chunkCount?: number;
}
/** Inputs the cascade rewrite-chunk step receives — one chunk per Map iteration. */
interface RenameCascadeChunkInput {
    readonly entityType: RenamableEntityType;
    readonly entityId: string;
    readonly tenantId?: string;
    /** Targets to rewrite in this transaction. Length must be 1..50. */
    readonly targets: ReadonlyArray<RenameCascadeRewriteTarget>;
    /**
     * Idempotency token uniquely identifying this chunk within the
     * cascade execution. Forwarded to `executeMultiWrite` so replayed
     * chunks land idempotently.
     */
    readonly chunkToken: string;
}
/** Outputs the cascade list-targets step emits to feed the Distributed Map state. */
interface RenameCascadeListOutput {
    readonly entityType: RenamableEntityType;
    readonly entityId: string;
    readonly tenantId?: string;
    readonly oldName: string;
    readonly newName: string;
    readonly oldNormalizedName: string;
    readonly newNormalizedName: string;
    readonly cursors: Record<string, string | null>;
    readonly chunks: ReadonlyArray<RenameCascadeChunkInput>;
    readonly exhausted: boolean;
    readonly itemsRewritten: number;
    readonly chunkCount: number;
}
/** Inputs the cascade finalize step receives. */
interface RenameCascadeFinalizeInput {
    readonly entityType: RenamableEntityType;
    readonly entityId: string;
    readonly tenantId?: string;
    readonly newName: string;
    readonly itemsRewritten: number;
    readonly chunkCount: number;
    readonly startedAt: string;
    /** Optional eventId / correlation for ADR-016 envelope chaining. */
    readonly eventId?: string;
    readonly correlationId?: string;
    readonly causationId?: string;
}
/** Outputs the cascade finalize step emits (used by tests + telemetry). */
interface RenameCascadeFinalizeOutput {
    readonly entityType: RenamableEntityType;
    readonly entityId: string;
    readonly tenantId?: string;
    readonly newName: string;
    readonly itemsRewritten: number;
    readonly chunkCount: number;
    readonly durationMs: number;
    readonly completedAt: string;
}
/** Env var the construct uses to inject the ops event bus name into the finalize Lambda. */
declare const RENAME_CASCADE_OPS_EVENT_BUS_ENV_VAR: "RENAME_CASCADE_OPS_EVENT_BUS_NAME";

export { RENAME_CASCADE_CONSUMER_NAME as R, RENAME_CASCADE_DEFAULT_CONCURRENCY as a, RENAME_CASCADE_FAILED_THRESHOLD as b, RENAME_CASCADE_OPS_EVENT_BUS_ENV_VAR as c, RENAME_CASCADE_SLOW_THRESHOLD_SECONDS as d, type RenameCascadeChunkInput as e, type RenameCascadeFinalizeInput as f, type RenameCascadeFinalizeOutput as g, type RenameCascadeListInput as h, type RenameCascadeListOutput as i };
