var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
var __typeError = (msg) => {
  throw TypeError(msg);
};
var __using = (stack, value, async) => {
  if (value != null) {
    if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
    var dispose, inner;
    if (async) dispose = value[__knownSymbol("asyncDispose")];
    if (dispose === void 0) {
      dispose = value[__knownSymbol("dispose")];
      if (async) inner = dispose;
    }
    if (typeof dispose !== "function") __typeError("Object not disposable");
    if (inner) dispose = function() {
      try {
        inner.call(this);
      } catch (e) {
        return Promise.reject(e);
      }
    };
    stack.push([async, dispose, value]);
  } else if (async) {
    stack.push([async]);
  }
  return value;
};
var __callDispose = (stack, error, hasError) => {
  var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
    return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
  };
  var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
  var next = (it) => {
    while (it = stack.pop()) {
      try {
        var result = it[1] && it[1].call(it[2]);
        if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
      } catch (e) {
        fail(e);
      }
    }
    if (hasError) throw error;
  };
  return next();
};
import { unreachable } from "../../../../shared/src/asserts.js";
import { must } from "../../../../shared/src/must.js";
import { Database } from "../../../../zqlite/src/db.js";
import { loadPermissions } from "../../auth/load-permissions.js";
import { isAdminPasswordValid, getServerVersion } from "../../config/zero-config.js";
import { StatementRunner } from "../../db/statements.js";
import { analyzeQuery } from "../analyze.js";
async function handleInspect(lc, body, cvr, client, inspectorDelegate, clientGroupID, cvrStore, config, headerOptions, userQueryURL, auth) {
  if (body.op !== "authenticate" && !inspectorDelegate.isAuthenticated(clientGroupID)) {
    lc.info?.(
      "Client not authenticated to access the inspector protocol. Sending authentication challenge"
    );
    client.sendInspectResponse(lc, {
      op: "authenticated",
      id: body.id,
      value: false
    });
    return;
  }
  try {
    switch (body.op) {
      case "queries": {
        const queryRows = await cvrStore.inspectQueries(
          lc,
          cvr.ttlClock,
          body.clientID
        );
        const enhancedRows = queryRows.map((row) => ({
          ...row,
          ast: row.ast ?? inspectorDelegate.getASTForQuery(row.queryID) ?? null,
          metrics: inspectorDelegate.getMetricsJSONForQuery(row.queryID)
        }));
        client.sendInspectResponse(lc, {
          op: "queries",
          id: body.id,
          value: enhancedRows
        });
        break;
      }
      case "metrics": {
        client.sendInspectResponse(lc, {
          op: "metrics",
          id: body.id,
          value: inspectorDelegate.getMetricsJSON()
        });
        break;
      }
      case "version":
        client.sendInspectResponse(lc, {
          op: "version",
          id: body.id,
          value: getServerVersion(config)
        });
        break;
      case "authenticate": {
        const password = body.value;
        const ok = isAdminPasswordValid(lc, config, password);
        if (ok) {
          inspectorDelegate.setAuthenticated(clientGroupID);
        } else {
          inspectorDelegate.clearAuthenticated(clientGroupID);
        }
        client.sendInspectResponse(lc, {
          op: "authenticated",
          id: body.id,
          value: ok
        });
        break;
      }
      case "analyze-query": {
        let ast = body.ast ?? body.value;
        let legacyQuery = true;
        if (body.name && body.args) {
          ast = await inspectorDelegate.transformCustomQuery(
            body.name,
            body.args,
            headerOptions,
            userQueryURL
          );
          legacyQuery = false;
        }
        if (ast === void 0) {
          throw new Error(
            "AST is required for analyze-query operation. Either provide an AST directly or ensure custom query transformation is configured."
          );
        }
        let permissions;
        if (legacyQuery) {
          var _stack = [];
          try {
            const db = __using(_stack, new Database(lc, config.replica.file));
            const dbRunner = new StatementRunner(db);
            const loaded = loadPermissions(lc, dbRunner, config.app.id, config);
            if (loaded.permissions) {
              permissions = loaded.permissions;
            } else {
              lc.info?.(
                "No permissions loaded; analyze-query will run without applying permissions."
              );
            }
          } catch (_) {
            var _error = _, _hasError = true;
          } finally {
            __callDispose(_stack, _error, _hasError);
          }
        }
        const result = await analyzeQuery(
          lc,
          config,
          must(cvr.clientSchema),
          ast,
          body.options?.syncedRows,
          body.options?.vendedRows,
          permissions,
          auth,
          body.options?.joinPlans
        );
        client.sendInspectResponse(lc, {
          op: "analyze-query",
          id: body.id,
          value: result
        });
        break;
      }
      default:
        unreachable(body);
    }
  } catch (e) {
    lc.error?.("Error handling inspect message", e);
    client.sendInspectResponse(lc, {
      op: "error",
      id: body.id,
      value: e.message
    });
  }
}
export {
  handleInspect
};
//# sourceMappingURL=inspect-handler.js.map
