import { assert } from "../../../shared/src/asserts.js";
import { must } from "../../../shared/src/must.js";
function completeOrdering(ast, getPrimaryKey) {
  const primaryKey = must(getPrimaryKey(ast.table));
  return {
    ...ast,
    ...ast.related ? {
      related: ast.related?.map((r) => ({
        ...r,
        subquery: completeOrdering(r.subquery, getPrimaryKey)
      }))
    } : void 0,
    ...ast.where ? {
      where: completeOrderingInCondition(ast.where, getPrimaryKey)
    } : void 0,
    orderBy: addPrimaryKeys(primaryKey, ast.orderBy)
  };
}
function assertOrderingIncludesPK(ordering, pk) {
  const orderingFields = ordering.map(([field]) => field);
  const missingFields = pk.filter((pkField) => !orderingFields.includes(pkField));
  assert(
    missingFields.length === 0,
    `Ordering must include all primary key fields. Missing: ${missingFields.join(
      ", "
    )}.`
  );
}
function completeOrderingInCondition(condition, getPrimaryKey) {
  if (!condition) {
    return condition;
  }
  if (condition.type === "simple") {
    return condition;
  }
  if (condition.type === "correlatedSubquery") {
    return {
      ...condition,
      related: {
        ...condition.related,
        subquery: completeOrdering(condition.related.subquery, getPrimaryKey)
      }
    };
  }
  condition.type;
  return {
    ...condition,
    conditions: condition.conditions.map(
      (c) => completeOrderingInCondition(c, getPrimaryKey)
    )
  };
}
function addPrimaryKeys(primaryKey, orderBy) {
  orderBy = orderBy ?? [];
  const primaryKeysToAdd = new Set(primaryKey);
  for (const [field] of orderBy) {
    primaryKeysToAdd.delete(field);
  }
  if (primaryKeysToAdd.size === 0) {
    return orderBy;
  }
  return [
    ...orderBy,
    ...[...primaryKeysToAdd].map((key) => [key, "asc"])
  ];
}
export {
  assertOrderingIncludesPK,
  completeOrdering
};
//# sourceMappingURL=complete-ordering.js.map
