import {
  DEFAULT_TENANT_ID
} from "./chunk-X27B5TCC.js";
import {
  init_ids,
  newId
} from "./chunk-F4WUVOLE.js";
import {
  init_clock,
  nowMs,
  toIso
} from "./chunk-HFDLUBWN.js";
import {
  getDrizzle,
  init_drizzle
} from "./chunk-RII4M3J2.js";
import {
  schema_exports
} from "./chunk-DDJOPRB7.js";

// src/db/environments.ts
init_drizzle();
init_ids();
init_clock();
import { eq, and, isNull, lt, gt, sql } from "drizzle-orm";
function hydrate(row) {
  let config = JSON.parse(row.config_json);
  if (config.type === "cloud" && config.provider && config.provider !== "anthropic") {
    config = { ...config, type: "self_hosted" };
  }
  return {
    type: "environment",
    id: row.id,
    name: row.name,
    description: row.description ?? null,
    config,
    metadata: row.metadata_json ? JSON.parse(row.metadata_json) : {},
    state: row.state,
    state_message: row.state_message,
    created_at: toIso(row.created_at),
    updated_at: toIso(row.updated_at),
    archived_at: row.archived_at ? toIso(row.archived_at) : null
  };
}
function createEnvironment(input) {
  const db = getDrizzle();
  const id = newId("env");
  const now = nowMs();
  db.insert(schema_exports.environments).values({
    id,
    name: input.name,
    description: input.description ?? null,
    config_json: JSON.stringify(input.config),
    metadata_json: JSON.stringify(input.metadata ?? {}),
    tenant_id: input.tenant_id ?? DEFAULT_TENANT_ID,
    state: "preparing",
    created_at: now,
    updated_at: now
  }).run();
  return getEnvironment(id);
}
function updateEnvironment(id, updates) {
  const db = getDrizzle();
  const row = db.select().from(schema_exports.environments).where(eq(schema_exports.environments.id, id)).get();
  if (!row) return null;
  const newName = updates.name !== void 0 ? updates.name : row.name;
  const newDescription = updates.description !== void 0 ? updates.description : row.description;
  const newConfigJson = updates.config !== void 0 ? JSON.stringify(updates.config) : row.config_json;
  const newMetadataJson = updates.metadata !== void 0 ? JSON.stringify(updates.metadata) : row.metadata_json ?? "{}";
  db.update(schema_exports.environments).set({
    name: newName,
    description: newDescription ?? null,
    config_json: newConfigJson,
    metadata_json: newMetadataJson,
    updated_at: nowMs()
  }).where(eq(schema_exports.environments.id, id)).run();
  return getEnvironment(id);
}
function getEnvironment(id) {
  const db = getDrizzle();
  const row = db.select().from(schema_exports.environments).where(eq(schema_exports.environments.id, id)).get();
  return row ? hydrate(row) : null;
}
function getEnvironmentRow(id) {
  const db = getDrizzle();
  return db.select().from(schema_exports.environments).where(eq(schema_exports.environments.id, id)).get() ?? null;
}
function updateEnvironmentState(id, state, message) {
  const db = getDrizzle();
  db.update(schema_exports.environments).set({ state, state_message: message ?? null }).where(eq(schema_exports.environments.id, id)).run();
}
function updateEnvironmentCheckpoint(id, checkpointId, templateSprite) {
  const db = getDrizzle();
  db.update(schema_exports.environments).set({ checkpoint_id: checkpointId, template_sandbox: templateSprite }).where(eq(schema_exports.environments.id, id)).run();
}
function archiveEnvironment(id) {
  const db = getDrizzle();
  const res = db.update(schema_exports.environments).set({ archived_at: nowMs() }).where(and(eq(schema_exports.environments.id, id), isNull(schema_exports.environments.archived_at))).run();
  return res.changes > 0;
}
function deleteEnvironment(id) {
  const db = getDrizzle();
  db.update(schema_exports.sessions).set({ archived_at: nowMs() }).where(
    and(
      eq(schema_exports.sessions.environment_id, id),
      isNull(schema_exports.sessions.archived_at)
    )
  ).run();
  const res = db.delete(schema_exports.environments).where(eq(schema_exports.environments.id, id)).run();
  return res.changes > 0;
}
function listEnvironments(opts) {
  const db = getDrizzle();
  const limit = Math.min(Math.max(opts.limit ?? 20, 1), 100);
  const orderDir = opts.order === "asc" ? "asc" : "desc";
  const includeArchived = opts.includeArchived ?? false;
  const conditions = [];
  if (!includeArchived) conditions.push(isNull(schema_exports.environments.archived_at));
  if (opts.cursor) {
    conditions.push(
      orderDir === "desc" ? lt(schema_exports.environments.id, opts.cursor) : gt(schema_exports.environments.id, opts.cursor)
    );
  }
  if (opts.tenantFilter != null) {
    conditions.push(eq(schema_exports.environments.tenant_id, opts.tenantFilter));
  }
  const where = conditions.length ? and(...conditions) : void 0;
  const orderClause = orderDir === "desc" ? sql`${schema_exports.environments.id} DESC` : sql`${schema_exports.environments.id} ASC`;
  const rows = where ? db.select().from(schema_exports.environments).where(where).orderBy(orderClause).limit(limit).all() : db.select().from(schema_exports.environments).orderBy(orderClause).limit(limit).all();
  return rows.map(hydrate);
}
function hasSessionsAttached(envId) {
  const db = getDrizzle();
  const row = db.select({ n: sql`COUNT(*)` }).from(schema_exports.sessions).where(
    and(
      eq(schema_exports.sessions.environment_id, envId),
      isNull(schema_exports.sessions.archived_at),
      sql`${schema_exports.sessions.status} != 'terminated'`
    )
  ).get();
  return (row?.n ?? 0) > 0;
}

export {
  createEnvironment,
  updateEnvironment,
  getEnvironment,
  getEnvironmentRow,
  updateEnvironmentState,
  updateEnvironmentCheckpoint,
  archiveEnvironment,
  deleteEnvironment,
  listEnvironments,
  hasSessionsAttached
};
