import {
  resolveContainerProvider,
  resolveProvider
} from "./chunk-ZKZME3DE.js";
import {
  getEnvironmentRow,
  updateEnvironmentState
} from "./chunk-GTYDSYTR.js";
import {
  installClaudeWrapper
} from "./chunk-7AFOH6YL.js";
import {
  init_ids,
  newId
} from "./chunk-F4WUVOLE.js";

// src/containers/setup.ts
import crypto from "crypto";
init_ids();
var SENTINEL_DIR = "/home/sprite";
function hashPackages(packages) {
  const canonical = JSON.stringify(packages ?? {}, Object.keys(packages ?? {}).sort());
  return crypto.createHash("sha256").update(canonical).digest("hex").slice(0, 16);
}
function buildInstallCommands(packages) {
  if (!packages) return [];
  const cmds = [];
  if (packages.apt?.length) {
    cmds.push(`apt-get update -qq && apt-get install -y -qq ${packages.apt.map(shellEscape).join(" ")}`);
  }
  if (packages.cargo?.length) {
    cmds.push(`cargo install ${packages.cargo.map(shellEscape).join(" ")}`);
  }
  if (packages.gem?.length) {
    cmds.push(`gem install ${packages.gem.map(shellEscape).join(" ")}`);
  }
  if (packages.go?.length) {
    for (const pkg of packages.go) cmds.push(`go install ${shellEscape(pkg)}`);
  }
  if (packages.npm?.length) {
    cmds.push(`npm install -g ${packages.npm.map(shellEscape).join(" ")}`);
  }
  if (packages.pip?.length) {
    cmds.push(`pip install ${packages.pip.map(shellEscape).join(" ")}`);
  }
  return cmds;
}
function shellEscape(s) {
  return `'${s.replace(/'/g, "'\\''")}'`;
}
async function prepareSprite(sandboxName, packages, provider) {
  const p = provider ?? await resolveContainerProvider();
  await installClaudeWrapper(sandboxName, p);
  const hash = hashPackages(packages);
  const sentinel = `${SENTINEL_DIR}/.claude-agents-setup-${hash}`;
  const installCmds = buildInstallCommands(packages);
  if (installCmds.length === 0) {
    await p.exec(sandboxName, ["bash", "-c", `touch ${sentinel}`]);
    return;
  }
  const script = [
    "set -euo pipefail",
    `if [ -f ${sentinel} ]; then exit 0; fi`,
    ...installCmds,
    `touch ${sentinel}`
  ].join(" && ");
  const result = await p.exec(sandboxName, ["bash", "-c", script], {
    timeoutMs: 30 * 6e4
  });
  if (result.exit_code !== 0) {
    throw new Error(`setup failed (${result.exit_code}): ${result.stderr.slice(0, 500)}`);
  }
}
function kickoffEnvironmentSetup(envId) {
  runEnvironmentSetup(envId).catch((err) => {
    const msg = err instanceof Error ? err.message : String(err);
    console.error(`[env ${envId}] setup failed:`, msg);
    try {
      updateEnvironmentState(envId, "failed", msg);
    } catch (dbErr) {
      console.error(`[env ${envId}] failed to record setup failure:`, dbErr);
    }
  });
}
async function runEnvironmentSetup(envId) {
  const row = getEnvironmentRow(envId);
  if (!row) throw new Error(`environment ${envId} not found`);
  if (row.state === "ready") return;
  const config = JSON.parse(row.config_json);
  const provider = await resolveProvider({ envConfigProvider: config?.provider });
  const hasPackages = config.packages && Object.values(config.packages).some((v) => v && v.length > 0);
  if (!hasPackages) {
    updateEnvironmentState(envId, "ready", null);
    return;
  }
  const templateName = `ca-env-tpl-${newId("env").slice(4, 16).toLowerCase()}`;
  await provider.create({ name: templateName });
  try {
    await prepareSprite(templateName, config.packages, provider);
    updateEnvironmentState(envId, "ready", null);
  } catch (err) {
    throw err;
  } finally {
    await provider.delete(templateName).catch(() => {
    });
  }
}

export {
  SENTINEL_DIR,
  prepareSprite,
  kickoffEnvironmentSetup
};
