import { a as CounterTarget } from './counter-apply-operation-DZM3MIDm.js';

/**
 * ADR-028 counter reconciliation — recompute the denormalized
 * control-plane counters from canonical data and repair drift.
 *
 * The atomic-ADD path ({@link applyCounterDeltaOperation}) maintains the
 * counters incrementally off domain events, but events can be missed,
 * replayed, or arrive after a record was created without one (rows that
 * predate the counter work). This operation is the correctness backstop
 * ADR-028 names: it ignores the current counter value, recomputes the
 * true value from canonical records, and writes the absolute recomputed
 * value back with a DynamoDB `SET` (not `ADD`). A `SET` repairs both
 * directions of drift and backfills an absent / `0` attribute to its
 * correct value in one write.
 *
 * Counter semantics recomputed here MUST match {@link counterEventRouter}:
 *
 * - `Tenant.usersInTenant` = # tenant-scoped Memberships in the tenant
 *   (membership with NO workspace reference).
 * - `Tenant.workspacesInTenant` = # Workspaces in the tenant.
 * - `Workspace.usersInWorkspace` = # workspace-scoped Memberships for the workspace.
 * - `Workspace.adminUsersInWorkspace` / `normalUsersInWorkspace` =
 *   # workspace-scoped RoleAssignments for the workspace, bucketed by
 *   {@link isAdminRoleAssignment} on the assignment's role level / role id.
 * - `User.tenantsForUser` = # tenant-scoped Memberships for the user.
 * - `User.workspacesForUser` = # workspace-scoped Memberships for the user.
 *
 * @see counter-apply-operation.ts — the incremental ADD path this reconciles against.
 * @see counter-event-router.ts — the event → counter semantics this mirrors.
 */
/** One counter's old → new transition, recorded only when `old !== new`. */
interface CounterDriftEntry {
    /** Which canonical entity the counter lives on. */
    readonly target: CounterTarget;
    /** Identity of the canonical record (tenantId for Tenant, workspaceId for Workspace, userId for User). */
    readonly id: string;
    /** Tenant the record belongs to (Workspace only; omitted for Tenant / User). */
    readonly tenantId?: string;
    /** The counter attribute name. */
    readonly counter: string;
    /** The value found on the record before reconciliation (0 when the attribute was absent). */
    readonly old: number;
    /** The recomputed-from-canonical value written back. */
    readonly new: number;
}

/**
 * ADR-028 counter-reconciliation driver — walks every canonical Tenant,
 * Workspace, and User, reconciles each record's denormalized counters
 * against canonical data, and accumulates a single drift report.
 *
 * Enumeration reuses the existing GSI1-sharded list operations
 * (`summary` mode — ids only, no per-record BatchGet hydration):
 *
 * - All Tenants via {@link listTenantsOperation}.
 * - Per tenant, all Workspaces in that tenant via
 *   {@link listWorkspacesOperation} (the workspace GSI1 partition is
 *   tenant-scoped).
 * - All Users via {@link listUsersOperation}.
 *
 * Each record is then handed to the matching per-target recompute
 * ({@link reconcileTenantCountersOperation},
 * {@link reconcileWorkspaceCountersOperation},
 * {@link reconcileUserCountersOperation}), which owns the SET-back repair
 * and returns the per-counter old → new drift it corrected.
 *
 * @see counter-reconcile-operation.ts — the per-target recompute + repair.
 */
/** Totals summarizing one reconciliation run, alongside the per-counter drift list. */
interface CounterReconcileReport {
    /** Every counter that changed across every record, in walk order. */
    readonly drift: Array<CounterDriftEntry>;
    /** How many canonical records of each kind were scanned. */
    readonly scanned: {
        readonly tenants: number;
        readonly workspaces: number;
        readonly users: number;
    };
    /** Total number of individual counters corrected (== `drift.length`). */
    readonly countersCorrected: number;
}

/**
 * @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/counter-reconciliation/counter-reconciliation-handler.md
 *
 * ADR-028 counter-reconciliation job handler. Invoked on demand (manual
 * `aws lambda invoke`, an operator runbook, or a scheduled trigger) — not
 * an EventBridge consumer. Walks every canonical Tenant / Workspace /
 * User, recomputes the denormalized counters from canonical data, repairs
 * any drift with a `SET` write, and logs the per-counter old → new drift
 * report.
 *
 * Idempotent by construction: each per-target recompute writes the
 * absolute recomputed value, so a second run over unchanged data corrects
 * nothing and reports zero drift. That is why the job needs no dedup
 * circuit-breaker (unlike the event-driven counter-maintenance consumer,
 * whose atomic ADDs are not idempotent).
 */
/** Dependency seam for tests; production wires the real driver. */
interface CounterReconciliationDependencies {
    /**
     * Run the full reconciliation sweep. Defaults to
     * {@link reconcileAllCountersOperation}; tests inject a fake.
     */
    readonly reconcileAll: () => Promise<CounterReconcileReport>;
}
/**
 * Test-visible orchestrator. The production `handler` calls this with the
 * real driver; unit tests inject a fake. Returns the drift report so an
 * invoker (or test) can assert on what was corrected.
 */
declare const runCounterReconciliation: (deps: CounterReconciliationDependencies) => Promise<CounterReconcileReport>;
declare const handler: () => Promise<CounterReconcileReport>;

export { type CounterReconciliationDependencies, handler, runCounterReconciliation };
