import {
  batchGetWithRetry,
  buildSkPrefix,
  dispatchListMode
} from "./chunk-V6AO5T57.mjs";
import {
  SHARD_COUNT,
  getDynamoControlService
} from "./chunk-EUIP2U5F.mjs";

// src/data/operations/control/workspace/workspace-list-operation.ts
var SK = "CURRENT";
function counterValue(value) {
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
}
async function listWorkspacesOperation(params) {
  const { context, tableName, mode = "full" } = params;
  const { tenantId } = context;
  const service = getDynamoControlService(tableName);
  const shardResults = await Promise.all(
    Array.from(
      { length: SHARD_COUNT },
      (_, shard) => service.entities.workspace.query.gsi1({ tenantId, gsi1Shard: String(shard) }).go()
    )
  );
  return dispatchListMode(mode, shardResults, {
    hydrate: (orderedIds) => batchGetWithRetry(
      service.entities.workspace,
      orderedIds.map((id) => ({ tenantId, id, sk: SK }))
    ),
    getId: (item) => item.id,
    // FULL mode (admin list default): read the ADR-028 counters off the
    // canonical record hydrated by BatchGet and expose them as
    // `resource.counts`. Missing counters render as 0.
    buildEntry: (id, item) => ({
      id,
      resource: {
        resourceType: "Workspace",
        id,
        ...JSON.parse(item.resource),
        counts: {
          usersInWorkspace: counterValue(item.usersInWorkspace),
          adminUsersInWorkspace: counterValue(item.adminUsersInWorkspace),
          normalUsersInWorkspace: counterValue(item.normalUsersInWorkspace)
        }
      }
    }),
    // SUMMARY mode reads only the GSI1 `summary` projection (no
    // counters); surface zeros so the shape stays uniform.
    buildSummaryEntry: (id, parsed) => ({
      id,
      resource: {
        resourceType: "Workspace",
        id,
        ...parsed,
        counts: {
          usersInWorkspace: 0,
          adminUsersInWorkspace: 0,
          normalUsersInWorkspace: 0
        }
      }
    })
  });
}

// src/data/operations/control/tenant/tenant-list-operation.ts
var SK2 = "CURRENT";
function counterValue2(value) {
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
}
async function listTenantsOperation(params) {
  const { tableName, mode = "full" } = params;
  const service = getDynamoControlService(tableName);
  const shardResults = await Promise.all(
    Array.from(
      { length: SHARD_COUNT },
      (_, shard) => service.entities.tenant.query.gsi1({ gsi1Shard: String(shard) }).go()
    )
  );
  return dispatchListMode(mode, shardResults, {
    hydrate: (orderedIds) => batchGetWithRetry(
      service.entities.tenant,
      orderedIds.map((id) => ({ tenantId: id, sk: SK2 }))
    ),
    getId: (item) => item.id,
    // FULL mode (admin list default): read the ADR-028 counters off the
    // canonical record hydrated by BatchGet and expose them as
    // `resource.counts`. Missing counters render as 0.
    buildEntry: (id, item) => ({
      id,
      resource: {
        resourceType: "Tenant",
        id,
        ...JSON.parse(item.resource),
        counts: {
          usersInTenant: counterValue2(item.usersInTenant),
          workspacesInTenant: counterValue2(item.workspacesInTenant)
        }
      }
    }),
    // SUMMARY mode reads only the GSI1 `summary` projection, which does
    // not carry the counters; surface zeros so the shape stays uniform.
    buildSummaryEntry: (id, parsed) => ({
      id,
      resource: {
        resourceType: "Tenant",
        id,
        ...parsed,
        counts: { usersInTenant: 0, workspacesInTenant: 0 }
      }
    })
  });
}

// src/data/operations/control/membership/membership-count-by-user-operation.ts
async function countMembershipsByUserOperation(params) {
  const { userId, mode = "all", tenantId, tableName } = params;
  if (mode === "workspaceInTenant" && !tenantId) {
    throw new Error(
      'countMembershipsByUserOperation: tenantId is required when mode === "workspaceInTenant"'
    );
  }
  const service = getDynamoControlService(tableName);
  const skPrefix = buildSkPrefix(mode, tenantId);
  const result = await service.entities.membershipUserProjection.query.record({ userId }).begins({ sk: skPrefix }).go({ pages: "all", attributes: ["membershipId"] });
  return (result.data ?? []).length;
}

// src/data/operations/control/membership/membership-list-by-workspace-operation.ts
async function membershipListByWorkspaceOperation(params) {
  const {
    tenantId,
    workspaceId,
    cursor = null,
    limit,
    order,
    tableName
  } = params;
  const service = getDynamoControlService(tableName);
  const goOptions = {
    cursor
  };
  if (limit !== void 0) {
    goOptions.limit = limit;
  }
  if (order !== void 0) {
    goOptions.order = order;
  }
  const result = await service.entities.membershipWorkspaceProjection.query.record({ tenantId, workspaceId }).begins({ sk: "MEMBERSHIP#" }).go(goOptions);
  const items = (result.data ?? []).map((row) => ({
    tenantId: row.tenantId,
    workspaceId: row.workspaceId,
    sk: row.sk,
    userId: row.userId,
    membershipId: row.membershipId,
    summary: row.summary,
    vid: row.vid,
    lastUpdated: row.lastUpdated,
    denormalizedUserName: row.denormalizedUserName
  }));
  return { items, cursor: result.cursor ?? null };
}

// src/data/operations/control/roleassignment/roleassignment-list-by-workspace-operation.ts
function buildSkPrefix2(roleId) {
  if (roleId === void 0 || roleId.length === 0) {
    return "ROLEASSIGNMENT#";
  }
  return `ROLEASSIGNMENT#${roleId}#`;
}
async function roleAssignmentListByWorkspaceOperation(params) {
  const {
    tenantId,
    workspaceId,
    roleId,
    cursor = null,
    limit,
    order,
    tableName
  } = params;
  const service = getDynamoControlService(tableName);
  const skPrefix = buildSkPrefix2(roleId);
  const goOptions = {
    cursor
  };
  if (limit !== void 0) {
    goOptions.limit = limit;
  }
  if (order !== void 0) {
    goOptions.order = order;
  }
  const result = await service.entities.roleAssignmentWorkspaceProjection.query.record({ tenantId, workspaceId }).begins({ sk: skPrefix }).go(goOptions);
  const items = (result.data ?? []).map((row) => ({
    tenantId: row.tenantId,
    workspaceId: row.workspaceId,
    sk: row.sk,
    userId: row.userId,
    roleId: row.roleId,
    roleAssignmentId: row.roleAssignmentId,
    summary: row.summary,
    vid: row.vid,
    lastUpdated: row.lastUpdated,
    denormalizedUserName: row.denormalizedUserName,
    denormalizedRoleName: row.denormalizedRoleName
  }));
  return { items, cursor: result.cursor ?? null };
}

export {
  countMembershipsByUserOperation,
  membershipListByWorkspaceOperation,
  roleAssignmentListByWorkspaceOperation,
  listWorkspacesOperation,
  listTenantsOperation
};
//# sourceMappingURL=chunk-AYHBFK3Y.mjs.map