import { astToZQL } from "../../ast-to-zql/src/ast-to-zql.js";
import { formatOutput } from "../../ast-to-zql/src/format.js";
import { assert } from "../../shared/src/asserts.js";
import { must } from "../../shared/src/must.js";
import { transformAndHashQuery } from "../../zero-cache/src/auth/read-authorizer.js";
import { hydrate } from "../../zero-cache/src/services/view-syncer/pipeline-driver.js";
import { mapAST } from "../../zero-protocol/src/ast.js";
import { hashOfAST } from "../../zero-protocol/src/query-hash.js";
import { buildPipeline } from "../../zql/src/builder/builder.js";
async function runAst(lc, clientSchema, ast, isTransformed, options) {
  const { clientToServerMapper, permissions, host } = options;
  const result = {
    warnings: [],
    syncedRows: void 0,
    syncedRowCount: 0,
    start: 0,
    end: 0,
    afterPermissions: void 0,
    readRows: void 0,
    readRowCountsByQuery: {},
    readRowCount: void 0
  };
  if (!isTransformed) {
    ast = mapAST(ast, must(clientToServerMapper));
  }
  if (options.applyPermissions) {
    result.warnings.push(
      "Permissions are deprecated and will be removed in an upcoming release. See: https://zero.rocicorp.dev/docs/auth."
    );
    const authData = options.authData ? JSON.parse(options.authData) : {};
    if (!options.authData) {
      result.warnings.push(
        "No auth data provided. Permission rules will compare to `NULL` wherever an auth data field is referenced."
      );
    }
    const auth = { decoded: authData };
    ast = transformAndHashQuery(
      lc,
      "clientGroupIDForAnalyze",
      ast,
      must(
        permissions,
        "Permissions are required when applyPermissions is true"
      ),
      auth,
      false
    ).transformedAst;
    result.afterPermissions = await formatOutput(ast.table + astToZQL(ast));
  }
  const pipeline = buildPipeline(ast, host, "query-id");
  const start = performance.now();
  let syncedRowCount = 0;
  const rowsByTable = {};
  const seenByTable = /* @__PURE__ */ new Set();
  for (const rowChange of hydrate(pipeline, hashOfAST(ast), clientSchema)) {
    if (rowChange === "yield") {
      continue;
    }
    assert(rowChange.type === "add");
    let rows = rowsByTable[rowChange.table];
    const s = rowChange.table + "." + JSON.stringify(rowChange.row);
    if (seenByTable.has(s)) {
      continue;
    }
    syncedRowCount++;
    seenByTable.add(s);
    if (options.syncedRows) {
      if (!rows) {
        rows = [];
        rowsByTable[rowChange.table] = rows;
      }
      rows.push(rowChange.row);
    }
  }
  const end = performance.now();
  if (options.syncedRows) {
    result.syncedRows = rowsByTable;
  }
  result.start = start;
  result.end = end;
  result.syncedRowCount = syncedRowCount;
  result.readRowCountsByQuery = host.debug?.getVendedRowCounts() ?? {};
  let readRowCount = 0;
  for (const c of Object.values(result.readRowCountsByQuery)) {
    for (const v of Object.values(c)) {
      readRowCount += v;
    }
  }
  result.readRowCount = readRowCount;
  if (options.vendedRows) {
    result.readRows = host.debug?.getVendedRows();
  }
  return result;
}
export {
  runAst
};
//# sourceMappingURL=run-ast.js.map
