import { readFileSync } from "node:fs";
import { spawnSync } from "node:child_process";
import { join } from "node:path";
import { loadRemoteConfig } from "./remote-build.mjs";
import { remoteTransport, shq } from "./remote-ssh.mjs";
import {
  buildBindingRecord,
  collectAllowlistedPaths,
  credentialsFingerprint,
  defaultHome,
  parseCodexAuthFile,
  resolveCodexAuthPath,
  resolveLaptopClaudeAccountHome,
  buildSeatClaudeConfig,
  writeLaptopBindingAtomic,
} from "./seat-account.mjs";
import { collectValidatedAllowlistMembers } from "./seat-archive.mjs";
import {
  decideSeatHost,
  defaultSeatStateDir,
  probeSeatHosts,
} from "./seat-discovery.mjs";
import { gitPreflight, deriveSeatIdentity, seatPaths } from "./seat-identity.mjs";
import { planSeatLaunch, dryRunSeatLaunchPlan } from "./seat-launch-planner.mjs";
import {
  resolveSeatModelToken,
  stripForwardedModelOverrides,
  validateInheritedModelEnv,
  buildSeatRuntimeEnv,
} from "./seat-model.mjs";
import {
  runPerSeatDoctor,
  buildTraverseProbeScript,
  buildLiveDoctorProbeScript,
  parseLiveDoctorProbe,
} from "./seat-doctor.mjs";
import {
  buildAccountTarRestoreFromStdin,
  buildCodexAuthInstallFromStdin,
  buildNetnsProvisionScript,
  buildProxyHealthScript,
  buildProxyUnitStartScript,
  buildProxyStopScript,
  buildSeatMetadataProxy,
  buildSeatProxyEnvWriteScript,
  buildNetnsTeardownScript,
  buildRollbackScript,
  buildExistenceProbeScript,
  parseExistenceProbe,
  planSeatProxy,
} from "./seat-proxy.mjs";
import {
  assertCommandFreeOfBlob,
  containsCredentialMarkers,
} from "./seat-transfer.mjs";
import {
  buildCheckoutCreateScript,
  buildImplementerIdentityProvisionScript,
  buildRemoteSeatArtifactsScript,
  buildSeatGitConfigScript,
  buildSeatJsonWriteScript,
  buildSeatLauncherStartScript,
  buildSeatResidueProbeScript,
  buildSeatStatusScript,
  buildVerifiedSeatStopScript,
  parseStatusOutput,
  buildAttachInvocation,
} from "./seat-runtime.mjs";
import { seatProfileShellPath } from "./home-path.mjs";
import {
  buildResumeRestoreFromStdin,
  buildResumeTransfer,
  parseResumeSessionId,
} from "./seat-resume-transfer.mjs";
import { SEAT_MODEL_SOURCE, SEAT_SCHEMA_VERSION } from "./seat-constants.mjs";

function forHost(cfg, host) {
  return { ...cfg, host };
}

function sshExecBlob(cfg, script, blob, deps = {}) {
  assertCommandFreeOfBlob(script, blob);
  const transport = deps.remoteTransport ?? remoteTransport;
  return transport(cfg, `bash -c ${shq(script)}`, {
    input: Buffer.isBuffer(blob) ? blob : Buffer.from(String(blob), "utf8"),
    timeoutSec: cfg.ssh_exec_timeout_sec ?? 1800,
    maxBuffer: deps.maxBuffer ?? 64 * 1024 * 1024,
  }, deps);
}

function sshExec(cfg, script, deps = {}) {
  const transport = deps.remoteTransport ?? remoteTransport;
  return transport(cfg, script, { timeoutSec: cfg.ssh_exec_timeout_sec ?? 1800 }, deps);
}

function fail(message, code = 1) {
  return { ok: false, message, code };
}

export function parseSeatRemoteArgv(argv) {
  const out = {
    command: "",
    host: "auto",
    account: "",
    project: "",
    model: null,
    claudeArgv: [],
  };
  let i = 0;
  if (argv[i] && ["launch", "status", "stop"].includes(argv[i])) {
    out.command = argv[i];
    i += 1;
  }
  while (i < argv.length) {
    const arg = argv[i];
    if (arg === "--") {
      out.claudeArgv = argv.slice(i + 1);
      break;
    }
    if (arg === "--host") {
      out.host = argv[++i] || "auto";
      i += 1;
      continue;
    }
    if (arg === "--account") {
      out.account = argv[++i] || "";
      i += 1;
      continue;
    }
    if (arg === "--project") {
      out.project = argv[++i] || "";
      i += 1;
      continue;
    }
    if (arg === "--model") {
      out.model = argv[++i] || "";
      i += 1;
      continue;
    }
    throw new Error(`seat-remote: unknown arg: ${arg}`);
  }
  return out;
}

export function buildSeatJsonRecord({ identity, host, model, proxyMeta }) {
  return {
    schemaVersion: SEAT_SCHEMA_VERSION,
    origin: identity.origin,
    account: identity.accountSlug,
    branch: identity.branchFull,
    upstream: identity.upstreamFull,
    checkout: `~/seats/${identity.seatId}/repo`,
    host,
    model,
    modelSource: SEAT_MODEL_SOURCE,
    proxy: proxyMeta,
  };
}

function rollbackOpts(mode, existed) {
  return { mode, existed };
}

function summarizeRollbackDetail(result) {
  return summarizeRemoteExecFailure(result);
}

const GIT_CLONE_NOISE_RE = /^(Cloning into |remote:|Receiving objects:|Resolving deltas:|Unpacking objects:|Updating files:|Filtering content:)/;
const FAILURE_MARKER_RE = /^[a-z][-a-z0-9]+(?::[a-z][-a-z0-9]+)?$/;

function normalizeExecText(text) {
  return String(text ?? "").replace(/\r/g, "\n");
}

function splitExecLines(text) {
  return normalizeExecText(text).split("\n").map((l) => l.trim()).filter(Boolean);
}

function redactExecLine(line) {
  const s = String(line);
  if (/access_token|refresh_token|credential-bytes|client_secret|Bearer\s+/i.test(s)) return "[redacted]";
  if (/\bgh[pousr]_[A-Za-z0-9_]{10,}\b/.test(s)) return "[redacted]";
  if (/\bgithub_pat_[A-Za-z0-9_]{10,}\b/.test(s)) return "[redacted]";
  if (/\bsk-[A-Za-z0-9-]{10,}\b/.test(s)) return "[redacted]";
  if (/gho_[A-Za-z0-9]+/.test(s)) return "[redacted]";
  if (/"secret"\s*:\s*"[^"]+"/i.test(s)) return "[redacted]";
  if (/"api[_-]?key"\s*:\s*"[^"]+"/i.test(s)) return "[redacted]";
  return s;
}

function isFailureMarker(line) {
  return FAILURE_MARKER_RE.test(line) && !line.startsWith("doctor ");
}

export function summarizeRemoteExecFailure(result, { maxLines = 8, maxChars = 2048 } = {}) {
  const stdoutLines = splitExecLines(result.stdout).map(redactExecLine);
  const stderrLines = splitExecLines(result.stderr).map(redactExecLine);
  const markers = stdoutLines.filter(isFailureMarker);
  const stderrUseful = stderrLines.filter((line) => !GIT_CLONE_NOISE_RE.test(line));
  const parts = [];
  if (markers.length) parts.push(...markers.slice(-3));
  if (stderrUseful.length) parts.push(...stderrUseful.slice(-maxLines));
  if (!parts.length && stderrLines.length) parts.push(stderrLines[stderrLines.length - 1]);
  if (!parts.length) parts.push(String(result.status));
  let detail = parts.slice(0, maxLines).join("; ");
  if (detail.length > maxChars) detail = `${detail.slice(0, maxChars - 3)}...`;
  return detail;
}

export function runLaunchRollback(hostCfg, seatId, identity, rollbackArgs, deps = {}) {
  const result = sshExec(hostCfg, buildRollbackScript(seatId, identity, rollbackArgs), deps);
  if (result.status !== 0) {
    return { ok: false, reason: `rollback-exec:${summarizeRollbackDetail(result)}` };
  }
  return { ok: true };
}

function failAfterRollback(hostCfg, seatId, identity, rollbackArgs, message, deps, { rollback = true } = {}) {
  if (rollback) {
    const rb = runLaunchRollback(hostCfg, seatId, identity, rollbackArgs, deps);
    if (!rb.ok) return fail(`${message}; ${rb.reason}`);
  }
  return fail(message);
}

export function seatRemoteStatus(parsed, deps = {}) {
  const home = deps.home ?? defaultHome();
  const cfg = deps.loadRemoteConfig?.() ?? loadRemoteConfig();
  if (!cfg) return fail("seat-remote: remote config disabled");
  if (!parsed.account || !parsed.project) return fail("seat-remote: --account and --project required");
  const identity = deriveSeatIdentity(parsed.project, parsed.account, deps);
  if (!identity.ok) return fail(`seat-remote: identity ${identity.reason}`);
  const stateDir = deps.stateDir ?? defaultSeatStateDir(home);
  const probes = probeSeatHosts(cfg, identity.seatId, stateDir, deps.log ?? (() => {}), deps);
  const decision = decideSeatHost({
    identity,
    requestedHost: parsed.host,
    probes,
    hosts: cfg.hosts,
  });
  if (!decision.ok) {
    return {
      ok: false,
      message: `seat-remote: host discovery failed (${decision.reason})`,
      identity,
      decision,
      probes,
    };
  }
  const hostCfg = forHost(cfg, decision.host);
  const paths = seatPaths(identity.seatId);
  const script = buildSeatStatusScript(identity.seatId, paths.unitName);
  const result = sshExec(hostCfg, script, deps);
  if (result.status !== 0) {
    return fail(`seat-remote: status command failed (${String(result.stderr).trim() || result.status})`);
  }
  const remoteStatus = parseStatusOutput(result.stdout);
  if (!remoteStatus.parseable) {
    return fail("seat-remote: status output unparseable");
  }
  if (!remoteStatus.ok) {
    const residueDetail = remoteStatus.residue.length
      ? remoteStatus.residue.join(",")
      : "unknown";
    return {
      ok: false,
      code: 1,
      message: `seat-remote: seat residue (${residueDetail})`,
      identity,
      decision,
      probes,
      status: remoteStatus,
    };
  }
  return {
    ok: true,
    identity,
    decision,
    probes,
    status: remoteStatus,
  };
}

export function seatRemoteStop(parsed, deps = {}) {
  const home = deps.home ?? defaultHome();
  const cfg = deps.loadRemoteConfig?.() ?? loadRemoteConfig();
  if (!cfg) return fail("seat-remote: remote config disabled");
  if (!parsed.account || !parsed.project) return fail("seat-remote: --account and --project required");
  const identity = deriveSeatIdentity(parsed.project, parsed.account, deps);
  if (!identity.ok) return fail(`seat-remote: identity ${identity.reason}`);
  const stateDir = deps.stateDir ?? defaultSeatStateDir(home);
  const probes = probeSeatHosts(cfg, identity.seatId, stateDir, deps.log ?? (() => {}), deps);
  const decision = decideSeatHost({ identity, requestedHost: parsed.host, probes, hosts: cfg.hosts });
  if (!decision.ok) {
    if (decision.reason === "runtime-corrupt") return fail("seat-remote: corrupt runtime — run seat-remote stop first");
    if (decision.reason === "duplicate-seat" || decision.reason === "hidden-seat") {
      return fail(`seat-remote: stop refused (${decision.reason})`);
    }
    const reachable = cfg.hosts.filter((h) => probes[h]?.reachable);
    if (reachable.length === 0) return fail("seat-remote: all hosts unreachable");
    const absentEverywhere = reachable.every((h) => !probes[h]?.seatPresent && !probes[h]?.scopeActive && !probes[h]?.socketLive);
    if (absentEverywhere) return { ok: true, host: reachable[0], seatId: identity.seatId, idempotent: true };
    return fail(`seat-remote: stop refused (${decision.reason})`);
  }
  const hostCfg = forHost(cfg, decision.host);
  const paths = seatPaths(identity.seatId);
  const scripts = [
    buildVerifiedSeatStopScript(identity.seatId, paths.unitName),
    buildProxyStopScript(identity.seatId),
    buildNetnsTeardownScript(identity.seatId),
  ].join("\n");
  const result = sshExec(hostCfg, scripts, deps);
  if (result.status !== 0) {
    return fail(`seat-remote: stop failed (${summarizeRemoteExecFailure(result)})`);
  }
  return { ok: true, host: decision.host, seatId: identity.seatId };
}

export function seatRemoteLaunch(parsed, deps = {}) {
  const home = deps.home ?? defaultHome();
  const cfg = deps.loadRemoteConfig?.() ?? loadRemoteConfig();
  if (!cfg) return fail("seat-remote: remote config disabled");
  if (!parsed.model) return fail("seat-remote: --model is required");
  const modelResolved = resolveSeatModelToken(parsed.model);
  if (!modelResolved.ok) {
    if (modelResolved.reason === "unsupported-security-boundary") return fail(modelResolved.message, 1);
    return fail(modelResolved.message || `seat-remote: ${modelResolved.reason}`);
  }
  const stripped = stripForwardedModelOverrides(parsed.claudeArgv);
  if (!stripped.ok) return fail(`seat-remote: duplicate/forwarded override (${stripped.reason})`);
  const inheritedViolations = validateInheritedModelEnv(deps.env ?? process.env, modelResolved.model);
  if (inheritedViolations.length) return fail(`seat-remote: inherited model env conflict (${inheritedViolations.join(",")})`);
  if (!parsed.account || !parsed.project) return fail("seat-remote: --account and --project required");
  const identity = deriveSeatIdentity(parsed.project, parsed.account, deps);
  if (!identity.ok) return fail(`seat-remote: identity ${identity.reason}`);
  const stateDir = deps.stateDir ?? defaultSeatStateDir(home);
  const counts = {};
  for (const host of cfg.hosts) {
    const hostCfg = forHost(cfg, host);
    const count = deps.remoteJobCount?.(hostCfg);
    if (Number.isInteger(count)) counts[host] = count;
  }
  const probes = probeSeatHosts(cfg, identity.seatId, stateDir, deps.log ?? (() => {}), deps);
  const decision = decideSeatHost({
    identity,
    requestedHost: parsed.host,
    probes,
    hosts: cfg.hosts,
    counts,
    cap: cfg.max_remote_jobs ?? 6,
  });
  if (!decision.ok) {
    if (decision.reason === "runtime-corrupt") return fail("seat-remote: corrupt runtime — run seat-remote stop first");
    return fail(`seat-remote: host discovery failed (${decision.reason})`);
  }
  const existingSeat = probes[decision.host]?.seat;
  if ((decision.action === "attach" || decision.action === "restart") && existingSeat) {
    if (existingSeat.model !== modelResolved.model) {
      return fail(`seat-remote: reattach model mismatch (bound ${existingSeat.model})`);
    }
  }
  const paths = seatPaths(identity.seatId);
  const hostCfg = forHost(cfg, decision.host);
  if (decision.action !== "attach" || decision.runtime !== "running") {
    const residueResult = sshExec(hostCfg, buildSeatResidueProbeScript(identity.seatId, paths.unitName), deps);
    if (residueResult.status !== 0) {
      const detail = summarizeRemoteExecFailure(residueResult);
      if (detail.includes("stale-seat-residue")) {
        return fail("seat-remote: stale seat residue — run seat-remote stop");
      }
      return fail(`seat-remote: launch blocked (${detail})`);
    }
  }
  const proxyPlan = planSeatProxy({ seatId: identity.seatId, boundModel: modelResolved.model });
  const claudeBinary = deps.claudeBinary ?? `${home}/.local/bin/claude`;
  const proxyBaseUrl = proxyPlan.proxyBaseUrl;
  const seatRuntimeEnv = buildSeatRuntimeEnv({
    PATH: "/usr/bin:/bin",
  }, modelResolved.model, proxyBaseUrl);
  const launchPlan = planSeatLaunch({
    boundModel: modelResolved.model,
    claudeBinary,
    claudeArgv: stripped.argv,
    settingsDir: paths.trustedConfigDir,
    mcpConfigPath: join(paths.trustedConfigDir, "empty-mcp.json"),
    seatEnv: seatRuntimeEnv,
    home,
  });
  const dry = dryRunSeatLaunchPlan(launchPlan, deps.projectSettings ?? {}, modelResolved.model);
  if (!dry.ok) return fail(`seat-remote: launch plan (${dry.errors.join(",")})`);

  if (decision.action === "attach" && decision.runtime === "running") {
    const doctorScript = [
      buildTraverseProbeScript(identity.seatId),
      buildLiveDoctorProbeScript({
        seatId: identity.seatId,
        port: proxyPlan.port,
        boundModel: modelResolved.model,
        accountSlug: identity.accountSlug,
        unitName: paths.unitName,
        identity,
      }),
    ].join("\n");
    const probeResult = sshExec(hostCfg, doctorScript, deps);
    const liveProbe = parseLiveDoctorProbe(probeResult.stdout);
    const doctor = runPerSeatDoctor({
      boundModel: modelResolved.model,
      seatId: identity.seatId,
      port: proxyPlan.port,
      proxyEnvContent: proxyPlan.envContent,
      launchPlan,
      liveProbe,
    });
    if (!doctor.ok) return fail(`seat-remote: doctor (${doctor.errors.join(",")})`);
    return {
      ok: true,
      action: "attach",
      host: decision.host,
      seatId: identity.seatId,
      model: modelResolved.model,
      attachExec: buildAttachInvocation(hostCfg, identity.seatId),
    };
  }

  if (decision.action === "create") {
    const preflight = gitPreflight(identity.projectRoot, deps);
    if (!preflight.ok) return fail(`seat-remote: git preflight (${preflight.errors.join(",")})`);
  }

  const codexAuthPath = resolveCodexAuthPath(home, identity.accountSlug, deps);
  if (!codexAuthPath && decision.action === "create") return fail("seat-remote: codex auth missing for account");
  let codexAuthRaw = "";
  if (codexAuthPath) {
    const parsedAuth = parseCodexAuthFile(codexAuthPath, deps);
    if (!parsedAuth.ok) return fail(`seat-remote: codex auth invalid (${parsedAuth.reason})`);
    codexAuthRaw = parsedAuth.raw;
  }

  const laptopAccountHome = resolveLaptopClaudeAccountHome(home, identity.accountSlug, deps);
  if (decision.action === "create" && !laptopAccountHome) {
    return fail(`seat-remote: claude account home missing (${identity.accountSlug})`);
  }
  const resumeSessionId = parseResumeSessionId(stripped.argv);
  let resumeBlob = null;
  if (resumeSessionId && decision.action === "create" && laptopAccountHome) {
    const resumeTransfer = buildResumeTransfer(laptopAccountHome, resumeSessionId, deps);
    if (!resumeTransfer.ok) return fail(resumeTransfer.message);
    resumeBlob = resumeTransfer.blob;
  }

  let accountTar = null;
  if (decision.action === "create" && laptopAccountHome) {
    const allowlist = collectValidatedAllowlistMembers(laptopAccountHome, deps);
    if (!allowlist.ok) return fail(`seat-remote: account allowlist (${allowlist.errors.join(",")})`);
    if (allowlist.members?.length) {
      const spawn = deps.spawnSync ?? spawnSync;
      const result = spawn("tar", ["-czf", "-", "-C", laptopAccountHome, ...allowlist.members], { encoding: "buffer", maxBuffer: 64 * 1024 * 1024 });
      if (result.status !== 0) return fail("seat-remote: account tar failed");
      accountTar = result.stdout;
    }
  }

  const proxyMeta = buildSeatMetadataProxy(identity.seatId, modelResolved.model, proxyPlan.port, proxyPlan.layout);
  const seatJson = buildSeatJsonRecord({ identity, host: decision.host, model: modelResolved.model, proxyMeta });
  const seatJsonContent = JSON.stringify(seatJson, null, 2);
  const preLauncherScripts = [];
  const launcherScripts = [];
  const isCreate = decision.action === "create";
  let existedBefore = {};
  if (isCreate) {
    const probeScript = buildExistenceProbeScript({ seatId: identity.seatId, accountSlug: identity.accountSlug });
    const probeResult = sshExec(hostCfg, probeScript, deps);
    if (probeResult.status !== 0) {
      return fail(`seat-remote: existence probe failed (${String(probeResult.stderr).trim() || probeResult.status})`);
    }
    existedBefore = parseExistenceProbe(probeResult.stdout);
  }
  const rollbackMode = isCreate ? "create" : "restart";
  const rollbackArgs = rollbackOpts(rollbackMode, existedBefore);
  if (isCreate) {
    preLauncherScripts.push(buildCheckoutCreateScript({
      seatId: identity.seatId,
      origin: identity.origin,
      branchFull: identity.branchFull,
      upstreamFull: identity.upstreamFull,
    }));
    preLauncherScripts.push(buildAccountBootstrapRemoteScript(laptopAccountHome, identity, deps));
    preLauncherScripts.push(buildSeatJsonWriteScript(identity.seatId, seatJsonContent));
  }
  preLauncherScripts.push(buildImplementerIdentityProvisionScript({ seatId: identity.seatId }));
  preLauncherScripts.push(buildRemoteSeatArtifactsScript({
    seatId: identity.seatId,
    settings: launchPlan.settings,
    seatEnv: launchPlan.env,
    forwardedArgv: stripped.argv,
  }));
  preLauncherScripts.push(buildSeatGitConfigScript({
    seatId: identity.seatId,
  }));
  preLauncherScripts.push(buildNetnsProvisionScript(identity.seatId, proxyPlan.port));
  preLauncherScripts.push(buildSeatProxyEnvWriteScript({
    seatId: identity.seatId,
    boundModel: modelResolved.model,
    port: proxyPlan.port,
    nsIp: proxyPlan.nsIp,
  }));
  preLauncherScripts.push(buildProxyUnitStartScript(identity.seatId));
  preLauncherScripts.push(buildProxyHealthScript(identity.seatId, proxyPlan.port));
  launcherScripts.push(buildSeatLauncherStartScript({
    seatId: identity.seatId,
    unitName: paths.unitName,
    netnsPath: proxyPlan.netnsPath,
    seatHost: decision.host,
    boundModel: modelResolved.model,
    accountSlug: identity.accountSlug,
  }));
  launcherScripts.push(buildTraverseProbeScript(identity.seatId));
  launcherScripts.push(buildLiveDoctorProbeScript({
    seatId: identity.seatId,
    port: proxyPlan.port,
    boundModel: modelResolved.model,
    accountSlug: identity.accountSlug,
    unitName: paths.unitName,
    identity,
  }));

  const remoteScriptBody = [...preLauncherScripts, ...launcherScripts].join("\n");
  if (containsCredentialMarkers(remoteScriptBody)) return fail("seat-remote: credential marker in remote script");

  if (codexAuthRaw) {
    const authScript = buildCodexAuthInstallFromStdin(identity.seatId);
    if (containsCredentialMarkers(authScript)) return fail("seat-remote: credential marker in auth script");
    const authResult = sshExecBlob(hostCfg, authScript, codexAuthRaw, deps);
    if (authResult.status !== 0) {
      return failAfterRollback(
        hostCfg,
        identity.seatId,
        identity,
        rollbackArgs,
        `seat-remote: codex auth transfer failed (${String(authResult.stderr).trim() || authResult.status})`,
        deps,
        { rollback: isCreate },
      );
    }
  }

  if (isCreate && accountTar) {
    const restoreScript = buildAccountTarRestoreFromStdin(identity);
    if (containsCredentialMarkers(restoreScript)) return fail("seat-remote: credential marker in restore script");
    const restoreResult = sshExecBlob(hostCfg, restoreScript, accountTar, deps);
    if (restoreResult.status !== 0) {
      return failAfterRollback(
        hostCfg,
        identity.seatId,
        identity,
        rollbackArgs,
        `seat-remote: account restore failed (${String(restoreResult.stderr).trim() || restoreResult.status})`,
        deps,
      );
    }
  }

  let result;
  if (isCreate && resumeBlob) {
    const preBody = preLauncherScripts.join("\n");
    if (containsCredentialMarkers(preBody)) return fail("seat-remote: credential marker in remote script");
    result = sshExec(hostCfg, preBody, deps);
    if (result.status !== 0) {
      return failAfterRollback(
        hostCfg,
        identity.seatId,
        identity,
        rollbackArgs,
        `seat-remote: launch failed (${summarizeRemoteExecFailure(result)})`,
        deps,
      );
    }
    const resumeScript = buildResumeRestoreFromStdin(identity, resumeSessionId);
    if (containsCredentialMarkers(resumeScript)) return fail("seat-remote: credential marker in resume script");
    const resumeResult = sshExecBlob(hostCfg, resumeScript, resumeBlob, deps);
    if (resumeResult.status !== 0) {
      return failAfterRollback(
        hostCfg,
        identity.seatId,
        identity,
        rollbackArgs,
        `seat-remote: resume restore failed (${String(resumeResult.stderr).trim() || resumeResult.status})`,
        deps,
      );
    }
    const launcherBody = launcherScripts.join("\n");
    if (containsCredentialMarkers(launcherBody)) return fail("seat-remote: credential marker in remote script");
    result = sshExec(hostCfg, launcherBody, deps);
  } else {
    result = sshExec(hostCfg, remoteScriptBody, deps);
  }
  if (result.status !== 0) {
    return failAfterRollback(
      hostCfg,
      identity.seatId,
      identity,
      rollbackArgs,
      `seat-remote: launch failed (${summarizeRemoteExecFailure(result)})`,
      deps,
    );
  }

  const liveProbe = parseLiveDoctorProbe(result.stdout);
  const doctor = runPerSeatDoctor({
    boundModel: modelResolved.model,
    seatId: identity.seatId,
    port: proxyPlan.port,
    proxyEnvContent: proxyPlan.envContent,
    launchPlan,
    liveProbe,
  });
  if (!doctor.ok) {
    return failAfterRollback(
      hostCfg,
      identity.seatId,
      identity,
      rollbackArgs,
      `seat-remote: doctor (${doctor.errors.join(",")})`,
      deps,
    );
  }

  if (isCreate) {
    const binding = buildBindingRecord({
      accountSlug: identity.accountSlug,
      seatId: identity.seatId,
      host: decision.host,
      model: modelResolved.model,
      credentialFingerprint: codexAuthRaw ? credentialsFingerprint(JSON.parse(codexAuthRaw)) : "",
    });
    if (!deps.skipLaptopBinding) writeLaptopBindingAtomic(home, identity.accountSlug, binding);
  }

  return {
    ok: true,
    action: decision.action,
    host: decision.host,
    seatId: identity.seatId,
    model: modelResolved.model,
    attachExec: buildAttachInvocation(hostCfg, identity.seatId),
  };
}

export function buildAccountBootstrapRemoteScript(laptopAccountHome, identity, deps = {}) {
  if (!laptopAccountHome) return "true";
  const entries = collectAllowlistedPaths(laptopAccountHome, deps);
  const lines = [
    "set -euo pipefail",
    `profile=${seatProfileShellPath(identity.accountSlug, identity.seatId)}`,
    "umask 077",
    "mkdir -p \"$profile/secure-storage\"",
    "chmod 700 \"$profile\"",
  ];
  for (const entry of entries) {
    if (entry.name === ".claude.json") {
      const raw = readFileSync(entry.path, "utf8");
      try {
        const projected = buildSeatClaudeConfig(raw);
        const content = JSON.stringify(projected);
        lines.push(`cat >\"$profile/.claude.json.tmp\" <<'CLAUDE_JSON_EOF'\n${content}\nCLAUDE_JSON_EOF`);
        lines.push("mv -f \"$profile/.claude.json.tmp\" \"$profile/.claude.json\"");
        lines.push("chmod 600 \"$profile/.claude.json\"");
      } catch {
        lines.push("echo profile-credential-material; exit 1");
      }
    }
  }
  return lines.join("\n");
}

export { SEAT_UNSUPPORTED_BOUNDARY } from "./seat-constants.mjs";
export {
  shouldFailClosedLocalClaudex,
  readLaptopBinding,
} from "./seat-account.mjs";
export { seatHostMatchesLocal, shouldSkipRemoteForSeatHost, attestSeatProcess, isAttestedSeatProcess } from "./seat-host-gate.mjs";
