import {
  dropActor,
  getActor
} from "./chunk-LAWTTG2E.js";
import {
  reconcileDockerOrphanSandboxes,
  reconcileOrphanSandboxes,
  releaseSession
} from "./chunk-BYQWYBZ3.js";
import {
  appendEvent,
  dropEmitter
} from "./chunk-4NRHKTBW.js";
import {
  archiveSession,
  getSessionRow,
  listIdleSessions,
  updateSessionStatus
} from "./chunk-SEGKFEG5.js";
import {
  tryResolveProvider
} from "./chunk-ZKZME3DE.js";
import {
  getEnvironment
} from "./chunk-GTYDSYTR.js";
import {
  expireWarm
} from "./chunk-G7KUVNDY.js";
import {
  getConfig
} from "./chunk-2MAQ6JFL.js";
import {
  init_clock,
  nowMs
} from "./chunk-HFDLUBWN.js";
import {
  getRuntime
} from "./chunk-UYTSKFGK.js";

// src/sessions/sweeper.ts
init_clock();
var sweeping = false;
var stopping = false;
function markStopping() {
  stopping = true;
}
function __resetSweeperState() {
  sweeping = false;
  stopping = false;
}
async function runSweep() {
  if (sweeping || stopping) return;
  sweeping = true;
  try {
    try {
      await evictIdleSessions();
    } catch (e) {
      console.warn("[sweeper] evict failed:", e);
    }
    const cfg = getConfig();
    if (cfg.spriteToken) {
      try {
        await reconcileOrphanSandboxes();
      } catch (e) {
        console.warn("[sweeper] reconcile sandboxes failed:", e);
      }
    }
    try {
      await reconcileDockerOrphanSandboxes();
    } catch (e) {
      if (!(e instanceof Error) || !e.message.includes("ENOENT")) {
        console.warn("[sweeper] reconcile docker failed:", e);
      }
    }
    try {
      await evictExpiredWarmContainers();
    } catch (e) {
      console.warn("[sweeper] warm pool eviction failed:", e);
    }
  } finally {
    sweeping = false;
  }
}
async function evictExpiredWarmContainers() {
  const expired = expireWarm(nowMs());
  if (expired.length === 0) return;
  console.log(`[sweeper] evicting ${expired.length} expired warm container(s)`);
  for (const entry of expired) {
    try {
      const envObj = getEnvironment(entry.envId);
      const provider = await tryResolveProvider({ envConfigProvider: envObj?.config?.provider });
      if (!provider) continue;
      await provider.delete(entry.sandboxName, entry.vaultSecrets);
      console.log(`[sweeper] deleted expired warm container: ${entry.sandboxName}`);
    } catch (err) {
      console.warn(`[sweeper] failed to delete warm container ${entry.sandboxName}:`, err);
    }
  }
}
async function evictIdleSessions() {
  if (stopping) return;
  const cfg = getConfig();
  const now = nowMs();
  const rows = listIdleSessions(cfg.sessionMaxAgeMs, now, 50);
  if (rows.length === 0) return;
  for (const { id: sessionId } of rows) {
    if (stopping) return;
    try {
      await getActor(sessionId).enqueue(async () => {
        const rt = getRuntime();
        if (rt.inFlightRuns.has(sessionId)) return;
        const row = getSessionRow(sessionId);
        if (!row || row.status !== "idle" || row.archived_at != null) return;
        const env = getEnvironment(row.environment_id);
        const maxAge = env?.config?.idle_timeout_ms ?? cfg.sessionMaxAgeMs;
        const base = row.idle_since ?? row.created_at;
        if (base + maxAge >= now) return;
        await releaseSession(sessionId);
        appendEvent(sessionId, {
          type: "session.status_terminated",
          payload: { reason: "idle_ttl" },
          origin: "server",
          processedAt: nowMs()
        });
        updateSessionStatus(sessionId, "terminated", "idle_ttl");
        archiveSession(sessionId);
      });
      dropActor(sessionId);
      dropEmitter(sessionId);
    } catch (err) {
      console.warn(`[sweeper] evict ${sessionId} failed:`, err);
    }
  }
}

export {
  markStopping,
  __resetSweeperState,
  runSweep
};
