import { shq, sshOpts, sshTarget } from "./remote-ssh.mjs";
import {
  claudeBinShellPath,
  guardBinShellDir,
  homeRel,
  launcherShellPath,
  seatCheckoutShellPath,
  seatHomeShellPath,
  seatStateDirShellPath,
  seatTmuxSocketShellPath,
  seatTrustedConfigShellDir,
  shellHomePath,
  shellPathAssign,
} from "./home-path.mjs";
import {
  SEAT_GUARD_REL,
  SEAT_IMPLEMENTER_EXEC_BIN,
  SEAT_IMPLEMENTER_EXEC_MODULE,
  SEAT_IMPLEMENTER_IDENTITY_MODULE,
  SEAT_COMMON_MODULE,
  SEAT_IMPLEMENTER_RUNTIME_BASE,
  SEAT_LAUNCHER_BIN,
  SEAT_SCOPE_ENTRY_BIN,
  SEAT_SCOPE_ENTRY_MANIFEST,
  SEAT_SCOPE_ENTRY_MODULE,
  SEAT_SCOPE_ENTRY_SUDOERS,
  SEAT_SCOPE_PROPERTIES,
  SEAT_SLICE,
  SEAT_TMUX_MEDIATOR_BIN,
  SEAT_TMUX_MEDIATOR_MODULE,
  SEAT_CONTROL_BASE,
  SEAT_CONTROL_BASE_MODE,
  SEAT_TRUSTED_CONFIG_DIR,
  SEAT_GIT_EMAIL_DOMAIN,
  SEATS_HOME_REL,
  SEAT_STATE_REL,
} from "./seat-constants.mjs";
import { buildAtomicWriteFromB64Script, buildAtomicWriteIdempotentScript, contentDigest } from "./seat-atomic.mjs";
import { buildSeatEnvJsonContent, extractSeatEnvJsonFields, validateForwardedArgv, validateSeatEnvObject } from "./seat-env.mjs";
import { implementerUsernameForSeat } from "./seat-implementer-identity.mjs";

export { implementerUsernameForSeat };

export function seatTrustedConfigDir(stateDir) {
  return `${stateDir}/${SEAT_TRUSTED_CONFIG_DIR}`;
}

export function buildScopePropertyArgs() {
  return Object.entries(SEAT_SCOPE_PROPERTIES).flatMap(([key, value]) => ["-p", `${key}=${value}`]);
}

export function buildImplementerIdentityProvisionScript({ seatId }) {
  return [
    "set -euo pipefail",
    `seat_id=${shq(seatId)}`,
    `sudo -n ${shq(SEAT_SCOPE_ENTRY_BIN)} --ensure-implementer-only --seat-id "$seat_id"`,
  ].join("\n");
}

export function buildSeatGitConfigScript({ seatId }) {
  const name = `Overdeck Seat ${seatId}`;
  const email = `${seatId}@${SEAT_GIT_EMAIL_DOMAIN}`;
  return [
    "set -euo pipefail",
    shellPathAssign("checkout", seatCheckoutShellPath(seatId)),
    `want_name=${shq(name)}`,
    `want_email=${shq(email)}`,
    "[ -d \"$checkout\" ] || { echo checkout-missing; exit 1; }",
    "read_name=$(git -C \"$checkout\" config --local --get user.name 2>/dev/null || true)",
    "read_email=$(git -C \"$checkout\" config --local --get user.email 2>/dev/null || true)",
    "[ \"$read_name\" = \"$want_name\" ] || git -C \"$checkout\" config --local user.name \"$want_name\"",
    "[ \"$read_email\" = \"$want_email\" ] || git -C \"$checkout\" config --local user.email \"$want_email\"",
    "actual_name=$(git -C \"$checkout\" config --local --get user.name)",
    "actual_email=$(git -C \"$checkout\" config --local --get user.email)",
    "[ \"$actual_name\" = \"$want_name\" ] || { echo seat-git-name-drift; exit 1; }",
    "[ \"$actual_email\" = \"$want_email\" ] || { echo seat-git-email-drift; exit 1; }",
  ].join("\n");
}

function installOverdeckModuleLines({ srcVar, dst, mode }) {
  return [
    `[ -f "$${srcVar}" ] || { echo ${srcVar}-missing; exit 1; }`,
    `sudo -n install -D -m ${mode} -o root -g root "$${srcVar}" ${shq(dst)}`,
    `actual=$(sha256sum ${shq(dst)} | awk '{print $1}')`,
    `want=$(sha256sum "$${srcVar}" | awk '{print $1}')`,
    `[ "$actual" = "$want" ] || { echo ${srcVar}-readback; exit 1; }`,
  ];
}

export function buildSeatImplementerPrereqScript() {
  return [
    "set -euo pipefail",
    `runtime_base=${shq(SEAT_IMPLEMENTER_RUNTIME_BASE)}`,
    `control_base=${shq(SEAT_CONTROL_BASE)}`,
    "exec_src=\"$HOME/.claude/bin/overdeck-seat-implementer-exec\"",
    "module_src=\"$HOME/.claude/lib/seat_implementer_exec.py\"",
    "common_src=\"$HOME/.claude/lib/seat_common.py\"",
    "identity_src=\"$HOME/.claude/lib/seat_implementer_identity.py\"",
    "mediator_src=\"$HOME/.claude/bin/overdeck-seat-tmux-mediator\"",
    "mediator_module_src=\"$HOME/.claude/lib/seat_tmux_mediator.py\"",
    `exec_dst=${shq(SEAT_IMPLEMENTER_EXEC_BIN)}`,
    `module_dst=${shq(SEAT_IMPLEMENTER_EXEC_MODULE)}`,
    `common_dst=${shq(SEAT_COMMON_MODULE)}`,
    `identity_dst=${shq(SEAT_IMPLEMENTER_IDENTITY_MODULE)}`,
    `mediator_dst=${shq(SEAT_TMUX_MEDIATOR_BIN)}`,
    `mediator_module_dst=${shq(SEAT_TMUX_MEDIATOR_MODULE)}`,
    "sudo -n true",
    "command -v setfacl >/dev/null 2>&1 || { echo setfacl-missing; exit 1; }",
    "sudo -n install -d -o root -g root -m 0755 /var/lib/overdeck",
    `sudo -n install -d -o root -g root -m 0710 "$runtime_base"`,
    `sudo -n install -d -o root -g root -m ${SEAT_CONTROL_BASE_MODE} "$control_base"`,
    "[ -x \"$exec_src\" ] || { echo seat-implementer-exec-missing; exit 1; }",
    ...installOverdeckModuleLines({ srcVar: "common_src", dst: SEAT_COMMON_MODULE, mode: "0644" }),
    ...installOverdeckModuleLines({ srcVar: "module_src", dst: SEAT_IMPLEMENTER_EXEC_MODULE, mode: "0644" }),
    ...installOverdeckModuleLines({ srcVar: "identity_src", dst: SEAT_IMPLEMENTER_IDENTITY_MODULE, mode: "0644" }),
    ...installOverdeckModuleLines({ srcVar: "mediator_module_src", dst: SEAT_TMUX_MEDIATOR_MODULE, mode: "0644" }),
    "sudo -n install -m 0755 -o root -g root \"$exec_src\" \"$exec_dst\"",
    "sudo -n install -m 0755 -o root -g root \"$mediator_src\" \"$mediator_dst\"",
  ].join("\n");
}

export function buildSeatImplementerAccessScript({ seatId }) {
  return [
    "set -euo pipefail",
    `seat_id=${shq(seatId)}`,
    "command -v setfacl >/dev/null 2>&1 || { echo setfacl-missing; exit 1; }",
    "[ -d \"$HOME/seats/$seat_id\" ] || mkdir -p \"$HOME/seats/$seat_id\"",
    "[ -d \"$HOME/.local/state/overdeck/seats/$seat_id\" ] || mkdir -p \"$HOME/.local/state/overdeck/seats/$seat_id\"",
    "chmod 700 \"$HOME/seats/$seat_id\" \"$HOME/.local/state/overdeck/seats/$seat_id\"",
  ].join("\n");
}

export function buildSeatScopeEntryInstallScript() {
  return [
    "set -euo pipefail",
    "wrapper_src=\"$HOME/.claude/bin/overdeck-seat-scope-entry\"",
    "module_src=\"$HOME/.claude/lib/seat_scope_entry.py\"",
    "common_src=\"$HOME/.claude/lib/seat_common.py\"",
    "identity_src=\"$HOME/.claude/lib/seat_implementer_identity.py\"",
    "exec_src=\"$HOME/.claude/bin/overdeck-seat-implementer-exec\"",
    "exec_module_src=\"$HOME/.claude/lib/seat_implementer_exec.py\"",
    "mediator_src=\"$HOME/.claude/bin/overdeck-seat-tmux-mediator\"",
    "mediator_module_src=\"$HOME/.claude/lib/seat_tmux_mediator.py\"",
    "launcher_src=\"$HOME/.claude/bin/seat-launcher\"",
    `wrapper_dst=${shq(SEAT_SCOPE_ENTRY_BIN)}`,
    `module_dst=${shq(SEAT_SCOPE_ENTRY_MODULE)}`,
    `manifest_dst=${shq(SEAT_SCOPE_ENTRY_MANIFEST)}`,
    `rule_file=${shq(SEAT_SCOPE_ENTRY_SUDOERS)}`,
    `exec_dst=${shq(SEAT_IMPLEMENTER_EXEC_BIN)}`,
    `mediator_dst=${shq(SEAT_TMUX_MEDIATOR_BIN)}`,
    `launcher_dst=${shq(SEAT_LAUNCHER_BIN)}`,
    "ssh_user=$(id -un)",
    "command -v setfacl >/dev/null 2>&1 || { echo setfacl-missing; exit 1; }",
    "[ -x \"$wrapper_src\" ] || { echo seat-scope-entry-missing; exit 1; }",
    "[ -f \"$module_src\" ] || { echo seat-scope-module-missing; exit 1; }",
    "[ -f \"$common_src\" ] || { echo seat-common-module-missing; exit 1; }",
    "[ -f \"$identity_src\" ] || { echo seat-identity-module-missing; exit 1; }",
    "[ -x \"$exec_src\" ] || { echo seat-implementer-exec-missing; exit 1; }",
    "[ -f \"$exec_module_src\" ] || { echo seat-implementer-module-missing; exit 1; }",
    "[ -x \"$mediator_src\" ] || { echo seat-tmux-mediator-missing; exit 1; }",
    "[ -f \"$mediator_module_src\" ] || { echo seat-tmux-mediator-module-missing; exit 1; }",
    "[ -x \"$launcher_src\" ] || { echo seat-launcher-missing; exit 1; }",
    "want_wrapper_sha=$(sha256sum \"$wrapper_src\" | awk '{print $1}')",
    "want_module_sha=$(sha256sum \"$module_src\" | awk '{print $1}')",
    "want_common_sha=$(sha256sum \"$common_src\" | awk '{print $1}')",
    "want_identity_sha=$(sha256sum \"$identity_src\" | awk '{print $1}')",
    "want_exec_sha=$(sha256sum \"$exec_src\" | awk '{print $1}')",
    "want_exec_module_sha=$(sha256sum \"$exec_module_src\" | awk '{print $1}')",
    "want_mediator_sha=$(sha256sum \"$mediator_src\" | awk '{print $1}')",
    "want_mediator_module_sha=$(sha256sum \"$mediator_module_src\" | awk '{print $1}')",
    "want_launcher_sha=$(sha256sum \"$launcher_src\" | awk '{print $1}')",
    "sudo -n mkdir -p /usr/local/lib/overdeck",
    `sudo -n install -d -o root -g root -m ${SEAT_CONTROL_BASE_MODE} ${shq(SEAT_CONTROL_BASE)}`,
    ...installOverdeckModuleLines({ srcVar: "module_src", dst: SEAT_SCOPE_ENTRY_MODULE, mode: "0644" }),
    ...installOverdeckModuleLines({ srcVar: "common_src", dst: SEAT_COMMON_MODULE, mode: "0644" }),
    ...installOverdeckModuleLines({ srcVar: "identity_src", dst: SEAT_IMPLEMENTER_IDENTITY_MODULE, mode: "0644" }),
    ...installOverdeckModuleLines({ srcVar: "exec_module_src", dst: SEAT_IMPLEMENTER_EXEC_MODULE, mode: "0644" }),
    ...installOverdeckModuleLines({ srcVar: "mediator_module_src", dst: SEAT_TMUX_MEDIATOR_MODULE, mode: "0644" }),
    "sudo -n install -m 0755 -o root -g root \"$wrapper_src\" \"$wrapper_dst\"",
    "sudo -n install -m 0755 -o root -g root \"$exec_src\" \"$exec_dst\"",
    "sudo -n install -m 0755 -o root -g root \"$mediator_src\" \"$mediator_dst\"",
    "sudo -n install -m 0755 -o root -g root \"$launcher_src\" \"$launcher_dst\"",
    "manifest_tmp=$(mktemp)",
    "printf '{\"wrapper_sha256\":\"%s\",\"module_sha256\":\"%s\",\"common_module_sha256\":\"%s\",\"implementer_exec_sha256\":\"%s\",\"implementer_module_sha256\":\"%s\",\"tmux_mediator_sha256\":\"%s\",\"tmux_mediator_module_sha256\":\"%s\",\"identity_module_sha256\":\"%s\",\"launcher_sha256\":\"%s\",\"ssh_user\":\"%s\"}\\n' \\",
    "  \"$want_wrapper_sha\" \"$want_module_sha\" \"$want_common_sha\" \"$want_exec_sha\" \"$want_exec_module_sha\" \\",
    "  \"$want_mediator_sha\" \"$want_mediator_module_sha\" \"$want_identity_sha\" \"$want_launcher_sha\" \"$ssh_user\" >\"$manifest_tmp\"",
    "sudo -n install -m 0600 -o root -g root \"$manifest_tmp\" \"$manifest_dst\"",
    "[ \"$(stat -c '%a' \"$manifest_dst\")\" = \"600\" ] || { echo seat-scope-manifest-mode; exit 1; }",
    "rm -f \"$manifest_tmp\"",
    "tmp=$(mktemp)",
    `printf '%s ALL=(root) NOPASSWD: ${SEAT_SCOPE_ENTRY_BIN} *\\n%s ALL=(root) NOPASSWD: ${SEAT_TMUX_MEDIATOR_BIN} *\\n%s ALL=(root) NOPASSWD: ${SEAT_IMPLEMENTER_EXEC_BIN} *\\n' \"$ssh_user\" \"$ssh_user\" \"$ssh_user\" >\"$tmp\"`,
    "sudo -n visudo -cf \"$tmp\" || { rm -f \"$tmp\"; echo seat-scope-sudoers-invalid; exit 1; }",
    `grep -Fq "NOPASSWD: ${SEAT_SCOPE_ENTRY_BIN}" "$tmp" || { rm -f "$tmp"; echo seat-scope-sudoers-scope; exit 1; }`,
    `grep -Fq "NOPASSWD: ${SEAT_TMUX_MEDIATOR_BIN}" "$tmp" || { rm -f "$tmp"; echo seat-scope-sudoers-mediator; exit 1; }`,
    `grep -Fq "NOPASSWD: ${SEAT_IMPLEMENTER_EXEC_BIN}" "$tmp" || { rm -f "$tmp"; echo seat-scope-sudoers-implementer; exit 1; }`,
    `[ "$(grep -c . \"$tmp\")" -eq 3 ] || { rm -f \"$tmp\"; echo seat-scope-sudoers-extra; exit 1; }`,
    "sudo -n install -m 0440 -o root -g root \"$tmp\" \"$rule_file\"",
    "rm -f \"$tmp\"",
    "sudo -n visudo -cf \"$rule_file\" || { echo seat-scope-sudoers-invalid; exit 1; }",
    `sudo -n ${shq(SEAT_SCOPE_ENTRY_BIN)} --install-check || { echo seat-scope-install-check; exit 1; }`,
    `sudo -n -l 2>/dev/null | grep -Fq ${shq(SEAT_SCOPE_ENTRY_BIN)} || { echo seat-scope-sudoers-list; exit 1; }`,
  ].join("\n");
}

export function buildSeatLauncherStartScript({
  seatId,
  unitName,
  netnsPath,
  seatHost,
  boundModel,
  accountSlug,
  slice = SEAT_SLICE,
  dryRun = false,
}) {
  const socketPath = seatTmuxSocketShellPath(seatId);
  const stateDir = seatStateDirShellPath(seatId);
  const launcherPath = launcherShellPath();
  const checkoutPath = seatCheckoutShellPath(seatId);
  const claudeBin = claudeBinShellPath();
  const guardBin = guardBinShellDir();
  return [
    buildSeatImplementerAccessScript({ seatId }),
    "set -euo pipefail",
    `unit=${shq(unitName)}`,
    shellPathAssign("socket", socketPath),
    shellPathAssign("state_dir", stateDir),
    shellPathAssign("launcher", launcherPath),
    `netns_path=${shq(netnsPath)}`,
    `seat_id=${shq(seatId)}`,
    `seat_host=${shq(seatHost)}`,
    `seat_model=${shq(boundModel)}`,
    `account=${shq(accountSlug)}`,
    shellPathAssign("checkout", checkoutPath),
    shellPathAssign("claude_bin", claudeBin),
    shellPathAssign("guard_bin", guardBin),
    `slice=${shq(slice)}`,
    "mkdir -p \"$state_dir\"",
    "chmod 700 \"$state_dir\"",
    "rm -f \"$socket\"",
    "[ -e \"$netns_path\" ] || { echo netns-missing-before-scope; exit 1; }",
    "[ -x \"$claude_bin\" ] || { echo claude-bin-missing; exit 1; }",
    "[ -d \"$checkout\" ] || { echo checkout-missing; exit 1; }",
    "export OVERDECK_SEAT_SSH_USER=\"$(id -un)\"",
    dryRun ? "dry_flag=--dry-run" : "dry_flag=",
    "sudo -n /usr/local/bin/overdeck-seat-scope-entry \\",
    "  --seat-id \"$seat_id\" \\",
    "  --netns-path \"$netns_path\" \\",
    "  --unit \"$unit\" \\",
    "  --socket \"$socket\" \\",
    "  --launcher \"$launcher\" \\",
    "  --slice \"$slice\" \\",
    "  --seat-host \"$seat_host\" \\",
    "  --seat-model \"$seat_model\" \\",
    "  --account-slug \"$account\" \\",
    "  --claude-bin \"$claude_bin\" \\",
    "  --guard-bin \"$guard_bin\" \\",
    "  --checkout \"$checkout\" \\",
    "  ${dry_flag}",
    "systemctl --user is-active --quiet \"$unit\" || { echo scope-not-active; exit 1; }",
    `sudo -n ${shq(SEAT_TMUX_MEDIATOR_BIN)} --seat-id "$seat_id" --socket "$socket" has-session -t main 2>/dev/null || { echo tmux-session-missing; exit 1; }`,
  ].join("\n");
}

function buildSeatResidueCollectFunction() {
  return [
    "_seat_collect_residue() {",
    "  residue_list=",
    "  scope_active=inactive",
    "  scope_load=not-found",
    "  scope_cgroup_procs=0",
    "  implementer_processes=0",
    "  socket_present=0",
    "  if systemctl --user is-active --quiet \"$unit\" 2>/dev/null; then scope_active=active; fi",
    "  scope_load=$(systemctl --user show \"$unit\" -p LoadState --value 2>/dev/null || echo not-found)",
    "  cg=$(systemctl --user show \"$unit\" -p ControlGroup --value 2>/dev/null || true)",
    "  if [ -n \"$cg\" ] && [ -f \"/sys/fs/cgroup${cg}/cgroup.procs\" ]; then",
    "    scope_cgroup_procs=$(wc -l < \"/sys/fs/cgroup${cg}/cgroup.procs\" | tr -d ' ')",
    "  fi",
    "  if [ -n \"${implementer_uid:-}\" ] && pgrep -u \"$implementer_uid\" >/dev/null 2>&1; then",
    "    implementer_processes=$(pgrep -c -u \"$implementer_uid\" 2>/dev/null || echo 0)",
    "  fi",
    "  if [ -S \"$socket\" ]; then socket_present=1; fi",
    "  if [ \"$scope_load\" = loaded ] && [ \"$scope_active\" = inactive ]; then",
    "    residue_list=\"${residue_list}${residue_list:+,}scope-loaded-inactive\"",
    "  fi",
    "  if [ \"$scope_cgroup_procs\" -gt 0 ]; then",
    "    residue_list=\"${residue_list}${residue_list:+,}scope-cgroup\"",
    "  fi",
    "  if [ \"$implementer_processes\" -gt 0 ]; then",
    "    residue_list=\"${residue_list}${residue_list:+,}implementer-processes\"",
    "  fi",
    "  if [ \"$socket_present\" = 1 ]; then",
    "    residue_list=\"${residue_list}${residue_list:+,}socket\"",
    "  fi",
    "}",
  ].join("\n");
}

export function buildSeatResiduePreamble(seatId) {
  const implementerUser = implementerUsernameForSeat(seatId);
  return [
    shellPathAssign("socket", seatTmuxSocketShellPath(seatId)),
    `implementer_user=${shq(implementerUser)}`,
    "implementer_uid=",
    "if id -u \"$implementer_user\" >/dev/null 2>&1; then implementer_uid=$(id -u \"$implementer_user\"); fi",
    buildSeatResidueCollectFunction(),
  ].join("\n");
}

export function buildSeatResidueProbeScript(seatId, unitName) {
  return [
    "set -euo pipefail",
    `seat_id=${shq(seatId)}`,
    `unit=${shq(unitName)}`,
    buildSeatResiduePreamble(seatId),
    "_seat_collect_residue",
    '[ -z "$residue_list" ] || { echo stale-seat-residue; exit 1; }',
  ].join("\n");
}

export function buildVerifiedSeatStopScript(seatId, unitName) {
  const mediator = shq(SEAT_TMUX_MEDIATOR_BIN);
  return [
    "set -euo pipefail",
    `seat_id=${shq(seatId)}`,
    `unit=${shq(unitName)}`,
    buildSeatResiduePreamble(seatId),
    `if [ -S "$socket" ] || sudo -n ${mediator} --seat-id "$seat_id" --socket "$socket" has-session -t main 2>/dev/null; then`,
    `  sudo -n ${mediator} --seat-id "$seat_id" --socket "$socket" kill-server`,
    "fi",
    "if systemctl --user is-active --quiet \"$unit\" 2>/dev/null || [ \"$(systemctl --user show \"$unit\" -p LoadState --value 2>/dev/null || echo not-found)\" = loaded ]; then",
    "  systemctl --user stop \"$unit\" || true",
    "fi",
    "systemctl --user reset-failed \"$unit\" 2>/dev/null || true",
    "for _try in $(seq 1 50); do",
    "  _seat_collect_residue",
    '  [ -z "$residue_list" ] && break',
    "  sleep 0.1",
    "done",
    "_seat_collect_residue",
    'if [ -n "$residue_list" ]; then',
    '  case ",$residue_list," in',
    '    *,implementer-processes,*) echo stop-residue-processes; exit 1 ;;',
    '    *,socket,*) echo stop-residue-socket; exit 1 ;;',
    '    *) echo stop-residue-scope; exit 1 ;;',
    "  esac",
    "fi",
  ].join("\n");
}

export function buildScopeStopScript(unitName) {
  void unitName;
  throw new Error("buildScopeStopScript is deprecated; use buildVerifiedSeatStopScript");
}

export function buildTmuxCleanupScript(seatId) {
  void seatId;
  throw new Error("buildTmuxCleanupScript is deprecated; use buildVerifiedSeatStopScript");
}

export function buildSeatStatusScript(seatId, unitName) {
  const mediator = shq(SEAT_TMUX_MEDIATOR_BIN);
  return [
    "set -euo pipefail",
    `seat_id=${shq(seatId)}`,
    `unit=${shq(unitName)}`,
    buildSeatResiduePreamble(seatId),
    "_seat_collect_residue",
    "socket_state=absent",
    `if sudo -n ${mediator} --seat-id "$seat_id" --socket "$socket" has-session -t main 2>/dev/null; then socket_state=present; fi`,
    "status_ok=1",
    '[ -n "$residue_list" ] && status_ok=0',
    'printf "scope=%s scope_load=%s socket=%s implementer_processes=%s scope_cgroup_procs=%s residue=%s ok=%s\\n" \\',
    '  "$scope_active" "$scope_load" "$socket_state" "$implementer_processes" "$scope_cgroup_procs" "${residue_list:-}" "$status_ok"',
    "if [ -f \"$HOME/seats/$seat_id/seat.json\" ]; then cat \"$HOME/seats/$seat_id/seat.json\"; fi",
  ].join("\n");
}

export function seatLauncherPath(home = "$HOME") {
  void home;
  return SEAT_LAUNCHER_BIN;
}

export function seatGuardBinPath(home) {
  return `${home}/${SEAT_GUARD_REL}`;
}

export function parseStatusOutput(stdout) {
  const lines = String(stdout || "").split("\n");
  const header = lines.find((l) => l.startsWith("scope="));
  if (!header) return { parseable: false, ok: false, residue: [] };
  const parts = Object.fromEntries(header.split(" ").map((p) => p.split("=")));
  if (!("ok" in parts)) return { parseable: false, ok: false, residue: [] };
  const jsonLine = lines.slice(lines.indexOf(header) + 1).join("\n").trim();
  let seat = null;
  if (jsonLine) {
    try { seat = JSON.parse(jsonLine); } catch { seat = null; }
  }
  const residue = parts.residue ? parts.residue.split(",").filter(Boolean) : [];
  const ok = parts.ok === "1" && residue.length === 0;
  return {
    parseable: true,
    ok,
    scope: parts.scope,
    scopeLoad: parts.scope_load,
    socket: parts.socket,
    implementerProcesses: Number(parts.implementer_processes || 0),
    scopeCgroupProcs: Number(parts.scope_cgroup_procs || 0),
    residue,
    seat,
  };
}

export function buildSeatJsonWriteScript(seatId, seatJsonContent) {
  const content = String(seatJsonContent).endsWith("\n") ? seatJsonContent : `${seatJsonContent}\n`;
  const seatHome = seatHomeShellPath(seatId);
  const seatJsonPath = shellHomePath(homeRel(SEATS_HOME_REL, seatId, "seat.json"));
  return [
    "set -euo pipefail",
    shellPathAssign("seat_home", seatHome),
    "mkdir -p \"$seat_home\"",
    buildAtomicWriteIdempotentScript({ finalPath: seatJsonPath, content, mode: "600", label: "seat-json" }),
    "chmod 600 \"$seat_home/seat.json\"",
  ].join("\n");
}

export function buildRemoteSeatArtifactsScript({
  seatId,
  settings,
  seatEnv,
  forwardedArgv = [],
}) {
  const envCheck = validateSeatEnvObject(extractSeatEnvJsonFields(seatEnv));
  if (!envCheck.ok) throw new Error(`seat-env-invalid:${envCheck.errors.join(",")}`);
  const fwdCheck = validateForwardedArgv(forwardedArgv);
  if (!fwdCheck.ok) throw new Error(`forwarded-invalid:${fwdCheck.errors.join(",")}`);
  const trustedDir = seatTrustedConfigShellDir(seatId);
  const stateDir = seatStateDirShellPath(seatId);
  const settingsJson = `${JSON.stringify(settings)}\n`;
  const mcpJson = `${JSON.stringify({ mcpServers: {} })}\n`;
  const forwardedJson = `${JSON.stringify(forwardedArgv)}\n`;
  const envJson = buildSeatEnvJsonContent(extractSeatEnvJsonFields(seatEnv));
  const settingsPath = shellHomePath(homeRel(SEAT_STATE_REL, seatId, SEAT_TRUSTED_CONFIG_DIR, "seat-settings.json"));
  const mcpPath = shellHomePath(homeRel(SEAT_STATE_REL, seatId, SEAT_TRUSTED_CONFIG_DIR, "empty-mcp.json"));
  const forwardedPath = shellHomePath(homeRel(SEAT_STATE_REL, seatId, SEAT_TRUSTED_CONFIG_DIR, "claude-forwarded.json"));
  const envPath = shellHomePath(homeRel(SEAT_STATE_REL, seatId, SEAT_TRUSTED_CONFIG_DIR, "seat-env.json"));
  return [
    "set -euo pipefail",
    shellPathAssign("state_dir", stateDir),
    shellPathAssign("trusted_dir", trustedDir),
    "mkdir -p \"$state_dir\" \"$trusted_dir\"",
    "chmod 700 \"$state_dir\" \"$trusted_dir\"",
    buildAtomicWriteFromB64Script({ finalPath: settingsPath, content: settingsJson, mode: "600", label: "seat-settings" }),
    buildAtomicWriteFromB64Script({ finalPath: mcpPath, content: mcpJson, mode: "600", label: "seat-mcp" }),
    buildAtomicWriteFromB64Script({ finalPath: forwardedPath, content: forwardedJson, mode: "600", label: "seat-forwarded" }),
    buildAtomicWriteFromB64Script({ finalPath: envPath, content: envJson, mode: "600", label: "seat-env" }),
    `chmod 600 ${settingsPath} ${mcpPath} ${forwardedPath} ${envPath}`,
  ].join("\n");
}


export function buildCheckoutCreateScript({ seatId, origin, branchFull, upstreamFull }) {
  const seatHome = seatHomeShellPath(seatId);
  const repo = seatCheckoutShellPath(seatId);
  const branchShort = branchFull.replace(/^refs\/heads\//, "");
  return [
    "set -euo pipefail",
    shellPathAssign("seat_home", seatHome),
    shellPathAssign("repo", repo),
    `origin=${shq(origin)}`,
    `branch=${shq(branchShort)}`,
    `upstream=${shq(upstreamFull)}`,
    "mkdir -p \"$seat_home\"",
    "if [ -d \"$repo/.git\" ]; then echo checkout-exists; exit 1; fi",
    "git clone \"$origin\" \"$repo\"",
    "cd \"$repo\"",
    "git fetch origin \"${branch}:refs/remotes/origin/${branch}\"",
    "git checkout -B \"$branch\" \"origin/$branch\"",
    "git branch --set-upstream-to=\"$upstream\" \"$branch\"",
    "git rev-parse HEAD",
    "git symbolic-ref -q HEAD",
    "git rev-parse --abbrev-ref --symbolic-full-name @{upstream}",
    "git remote get-url origin",
  ].join("\n");
}

export function buildAttachInvocation(cfg, seatId) {
  assertSafeSeatId(seatId);
  const socketExpr = seatTmuxSocketShellPath(seatId);
  const tmuxCmd = `sudo -n ${SEAT_TMUX_MEDIATOR_BIN} --seat-id ${shq(seatId)} --socket ${socketExpr} attach-session -t main`;
  return {
    cmd: "ssh",
    args: [...sshOpts(cfg), "-t", sshTarget(cfg), tmuxCmd],
  };
}

function assertSafeSeatId(seatId) {
  if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(String(seatId ?? ""))) {
    throw new Error(`unsafe seatId: ${seatId}`);
  }
}

export { contentDigest, validateForwardedArgv, validateSeatEnvObject };
