import { assert } from "../../../shared/src/asserts.js";
import { stringCompare } from "../../../shared/src/string-compare.js";
import { valuesEqual } from "./data.js";
function constraintMatchesRow(constraint, row) {
  for (const key in constraint) {
    if (!valuesEqual(row[key], constraint[key])) {
      return false;
    }
  }
  return true;
}
function constraintsAreCompatible(left, right) {
  for (const key in left) {
    if (key in right && !valuesEqual(left[key], right[key])) {
      return false;
    }
  }
  return true;
}
function constraintMatchesPrimaryKey(constraint, primary) {
  return keyMatchesPrimaryKey(Object.keys(constraint), primary);
}
function keyMatchesPrimaryKey(key, primary) {
  const constraintKeys = [...key];
  if (constraintKeys.length !== primary.length) {
    return false;
  }
  constraintKeys.sort(stringCompare);
  for (let i = 0; i < constraintKeys.length; i++) {
    if (constraintKeys[i] !== primary[i]) {
      return false;
    }
  }
  return true;
}
function pullSimpleAndComponents(condition) {
  if (condition.type === "and") {
    return condition.conditions.flatMap(pullSimpleAndComponents);
  }
  if (condition.type === "simple") {
    return [condition];
  }
  if (condition.type === "or" && condition.conditions.length === 1) {
    return pullSimpleAndComponents(condition.conditions[0]);
  }
  return [];
}
function primaryKeyConstraintFromFilters(condition, primary) {
  if (condition === void 0) {
    return void 0;
  }
  const conditions = pullSimpleAndComponents(condition);
  if (conditions.length === 0) {
    return void 0;
  }
  const ret = {};
  for (const subCondition of conditions) {
    if (subCondition.op === "=") {
      const column = extractColumn(subCondition);
      if (column !== void 0) {
        if (!primary.includes(column.name)) {
          continue;
        }
        ret[column.name] = column.value;
      }
    }
  }
  if (Object.keys(ret).length !== primary.length) {
    return void 0;
  }
  return ret;
}
function extractColumn(condition) {
  if (condition.left.type === "column") {
    assert(
      condition.right.type === "literal",
      () => `extractColumn: expected right side to be literal, got ${condition.right.type}`
    );
    return { name: condition.left.name, value: condition.right.value };
  }
  return void 0;
}
export {
  constraintMatchesPrimaryKey,
  constraintMatchesRow,
  constraintsAreCompatible,
  keyMatchesPrimaryKey,
  primaryKeyConstraintFromFilters,
  pullSimpleAndComponents
};
//# sourceMappingURL=constraint.js.map
