import {
  SANDBOX_BACKEND_IDS,
  WU_OPTIONS,
  buildSandboxProfile,
  createLinuxSandboxBackend,
  createMacosSandboxBackend,
  createWUParser,
  createWindowsSandboxBackend,
  resolveLocation,
  resolveSandboxBackendForPlatform,
  runCLI
} from "./chunk-2GXVIN57.js";
import {
  readWURaw
} from "./chunk-NRIZR3A7.js";
import {
  WU_PATHS,
  defaultWorktreeFrom
} from "./chunk-6HO4GWJE.js";
import {
  EXIT_CODES,
  LOG_PREFIX
} from "./chunk-DWMLTXKQ.js";
import {
  WORKSPACE_CONFIG_FILE_NAME,
  WORKSPACE_V2_KEYS
} from "./chunk-V6OJGLBA.js";
import {
  die
} from "./chunk-RXRKBBSM.js";

// src/wu-sandbox.ts
import { existsSync, readFileSync } from "fs";
import path from "path";
import { spawn } from "child_process";
import { parse as parseYaml } from "yaml";
var PREFIX = LOG_PREFIX.CLAIM.replace("wu-claim", "wu:sandbox");
var DEFAULT_ALLOW_UNSANDBOXED_ENV_VAR = "LUMENFLOW_SANDBOX_ALLOW_UNSANDBOXED";
var SOFTWARE_DELIVERY_KEY = WORKSPACE_V2_KEYS.SOFTWARE_DELIVERY;
function toNormalizedAbsolute(targetPath) {
  const normalized = path.resolve(targetPath);
  return normalized.length > 1 && normalized.endsWith(path.sep) ? normalized.slice(0, -1) : normalized;
}
function isWithinRoot(candidatePath, rootPath) {
  const candidateKey = process.platform === "win32" ? candidatePath.toLowerCase() : candidatePath;
  const rootKey = process.platform === "win32" ? rootPath.toLowerCase() : rootPath;
  return candidateKey === rootKey || candidateKey.startsWith(`${rootKey}${path.sep}`);
}
function parsePolicyConfig(value) {
  if (!value || typeof value !== "object") {
    return {};
  }
  return value;
}
function readWorkspaceSoftwareDelivery(projectRoot) {
  const configPath = path.join(projectRoot, WORKSPACE_CONFIG_FILE_NAME);
  if (!existsSync(configPath)) {
    return null;
  }
  try {
    const parsed = parseYaml(readFileSync(configPath, "utf8"));
    if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
      return null;
    }
    const workspace = parsed;
    const softwareDelivery = workspace[SOFTWARE_DELIVERY_KEY];
    if (!softwareDelivery || typeof softwareDelivery !== "object" || Array.isArray(softwareDelivery)) {
      return null;
    }
    return softwareDelivery;
  } catch {
    return null;
  }
}
function readSandboxPolicy(projectRoot) {
  const softwareDelivery = readWorkspaceSoftwareDelivery(projectRoot);
  if (!softwareDelivery) {
    return {
      allowUnsandboxedEnvVar: DEFAULT_ALLOW_UNSANDBOXED_ENV_VAR,
      extraWritableRoots: [],
      denyWritableRoots: []
    };
  }
  const sandbox = parsePolicyConfig(softwareDelivery.sandbox);
  const allowUnsandboxedEnvVar = typeof sandbox.allow_unsandboxed_fallback_env === "string" && sandbox.allow_unsandboxed_fallback_env.trim() !== "" ? sandbox.allow_unsandboxed_fallback_env.trim() : DEFAULT_ALLOW_UNSANDBOXED_ENV_VAR;
  const extraWritableRoots = Array.isArray(sandbox.extra_writable_roots) ? sandbox.extra_writable_roots.filter((value) => typeof value === "string") : [];
  const denyWritableRoots = Array.isArray(sandbox.deny_writable_roots) ? sandbox.deny_writable_roots.filter((value) => typeof value === "string") : [];
  return {
    allowUnsandboxedEnvVar,
    extraWritableRoots,
    denyWritableRoots
  };
}
function extractSandboxCommandFromArgv(argv) {
  const separator = argv.indexOf("--");
  if (separator === -1 || separator === argv.length - 1) {
    return [];
  }
  return argv.slice(separator + 1);
}
function parseWuSandboxOptions(argv = process.argv) {
  const opts = createWUParser({
    name: "wu-sandbox",
    description: "Execute a command through the sandbox backend for this platform",
    options: [WU_OPTIONS.id, WU_OPTIONS.worktree],
    required: ["id"],
    allowPositionalId: true
  });
  const command = extractSandboxCommandFromArgv(argv);
  return {
    id: String(opts.id).toUpperCase(),
    worktree: opts.worktree,
    command
  };
}
function resolveCandidateRoots(projectRoot, policy) {
  const deniedRoots = policy.denyWritableRoots.map(
    (entry) => path.isAbsolute(entry) ? toNormalizedAbsolute(entry) : toNormalizedAbsolute(path.join(projectRoot, entry))
  );
  const extras = policy.extraWritableRoots.map(
    (entry) => path.isAbsolute(entry) ? toNormalizedAbsolute(entry) : toNormalizedAbsolute(path.join(projectRoot, entry))
  );
  return extras.filter((extra) => !deniedRoots.some((denied) => isWithinRoot(extra, denied)));
}
function resolveWorktreeFromWu(projectRoot, wuId) {
  const wuPath = path.join(projectRoot, WU_PATHS.WU(wuId));
  if (!existsSync(wuPath)) {
    return null;
  }
  try {
    const doc = readWURaw(wuPath);
    const defaultWorktree = defaultWorktreeFrom(doc);
    return defaultWorktree ? path.resolve(projectRoot, defaultWorktree) : null;
  } catch {
    return null;
  }
}
async function resolveWorktreePath(projectRoot, wuId, explicitWorktree, cwd) {
  if (explicitWorktree) {
    return path.isAbsolute(explicitWorktree) ? path.resolve(explicitWorktree) : path.resolve(projectRoot, explicitWorktree);
  }
  const location = await resolveLocation(cwd);
  if (location.type === "worktree") {
    return path.resolve(location.gitRoot);
  }
  const fromWu = resolveWorktreeFromWu(projectRoot, wuId);
  if (fromWu) {
    return fromWu;
  }
  die(
    `Unable to determine worktree path for ${wuId}.
Run from the claimed worktree or provide --worktree <path>.`
  );
}
function createBackendForCurrentPlatform() {
  const resolution = resolveSandboxBackendForPlatform();
  if (!resolution.supported) {
    return null;
  }
  if (resolution.id === SANDBOX_BACKEND_IDS.LINUX) {
    return createLinuxSandboxBackend();
  }
  if (resolution.id === SANDBOX_BACKEND_IDS.MACOS) {
    return createMacosSandboxBackend();
  }
  if (resolution.id === SANDBOX_BACKEND_IDS.WINDOWS) {
    return createWindowsSandboxBackend();
  }
  return null;
}
function resolveAllowUnsandboxedFallback(env, envVarName) {
  return env[envVarName] === "1";
}
async function buildSandboxExecution(input) {
  const cwd = input.cwd || process.cwd();
  const location = await resolveLocation(cwd);
  const projectRoot = path.resolve(location.mainCheckout || cwd);
  const policy = readSandboxPolicy(projectRoot);
  const extraWritableRoots = resolveCandidateRoots(projectRoot, policy);
  const worktreePath = await resolveWorktreePath(projectRoot, input.id, input.worktree, cwd);
  const allowUnsandboxedFallback = resolveAllowUnsandboxedFallback(
    process.env,
    policy.allowUnsandboxedEnvVar
  );
  const profile = buildSandboxProfile({
    projectRoot,
    worktreePath,
    wuId: input.id,
    extraWritableRoots
  });
  const backend = createBackendForCurrentPlatform();
  if (!backend) {
    const unsupportedPlan = allowUnsandboxedFallback ? {
      backendId: SANDBOX_BACKEND_IDS.UNSUPPORTED,
      enforced: false,
      failClosed: false,
      warning: "Running unsandboxed because this platform does not have a hardened sandbox backend."
    } : {
      backendId: SANDBOX_BACKEND_IDS.UNSUPPORTED,
      enforced: false,
      failClosed: true,
      reason: `No hardened sandbox backend is available for this platform. Set ${policy.allowUnsandboxedEnvVar}=1 to allow explicit unsandboxed fallback.`
    };
    return {
      profile,
      plan: unsupportedPlan,
      worktreePath,
      policy,
      allowUnsandboxedFallback
    };
  }
  const plan = backend.resolveExecution({
    profile,
    command: input.command,
    allowUnsandboxedFallback
  });
  return {
    profile,
    plan,
    worktreePath,
    policy,
    allowUnsandboxedFallback
  };
}
async function runCommand(command, args, cwd) {
  return new Promise((resolve, reject) => {
    const child = spawn(command, args, {
      cwd,
      stdio: "inherit",
      env: process.env
    });
    child.on("error", reject);
    child.on("exit", (code, signal) => {
      if (signal) {
        resolve(EXIT_CODES.ERROR);
      } else {
        resolve(code ?? EXIT_CODES.ERROR);
      }
    });
  });
}
async function runWuSandbox(input) {
  if (!input.command || input.command.length === 0) {
    die("No command provided. Usage: pnpm wu:sandbox --id WU-XXXX -- <command> [args...]");
  }
  const { plan, worktreePath, policy } = await buildSandboxExecution(input);
  if (plan.failClosed) {
    die(
      `${plan.reason || "Sandbox backend failed closed."}
To allow explicit unsandboxed fallback for this command, set ${policy.allowUnsandboxedEnvVar}=1.`
    );
  }
  if (plan.warning) {
    console.warn(`${PREFIX} Warning: ${plan.warning}`);
  }
  const commandToRun = plan.enforced && plan.invocation ? plan.invocation.command : input.command[0];
  const commandArgs = plan.enforced && plan.invocation ? plan.invocation.args : input.command.slice(1);
  if (plan.enforced) {
    console.log(`${PREFIX} Running command with ${plan.backendId} sandbox backend.`);
  } else {
    console.log(`${PREFIX} Running command unsandboxed (explicit fallback).`);
  }
  return runCommand(commandToRun, commandArgs, worktreePath);
}
async function main() {
  const options = parseWuSandboxOptions(process.argv);
  const exitCode = await runWuSandbox(options);
  process.exit(exitCode);
}
if (import.meta.main) {
  void runCLI(main);
}

export {
  readSandboxPolicy,
  extractSandboxCommandFromArgv,
  resolveAllowUnsandboxedFallback,
  runWuSandbox,
  main
};
