#!/usr/bin/env bash
set -euo pipefail

# @describe Start (or reuse) a sandbox Docker container with a bind-mounted workspace.
# @option --workspace! Host path to mount into the container at /work (must be under $AICHAT_SANDBOX_BASE).
# @option --image Docker image to use. Default: aichat-docker:latest
# @option --name Optional explicit container name. Default: auto-generated.
# @option --network Enable network access (true/false). Default: true
# @option --ttl_minutes Optional TTL label for cleanup tooling. Default: 0 (no TTL)

main() {
  local base="${AICHAT_SANDBOX_BASE:-$HOME/aichat-workspaces}"
  local image="${argc_image:-aichat-docker:latest}"
  local net="${argc_network:-true}"
  local ttl="${argc_ttl_minutes:-0}"

  mkdir -p "$base"

  local ws
  ws="$(realpath -m "${argc_workspace}")"

  local base_real
  base_real="$(realpath -m "$base")"
  case "$ws" in
    "$base_real"/*) ;;
    *)
      echo "ERROR: workspace must be under $base_real (got $ws)" >> "$LLM_OUTPUT"
      exit 2
      ;;
  esac

  mkdir -p "$ws"

  local name="${argc_name:-aichat-sbx-$(date +%s)-$RANDOM}"

  if docker ps -a --format '{{.Names}}' | grep -qx "$name"; then
    printf '{"container":"%s","workspace":"%s","status":"already-exists"}\n' "$name" "$ws" >> "$LLM_OUTPUT"
    return 0
  fi

  local net_arg=()
  if [[ "$net" == "false" ]]; then
    net_arg+=(--network none)
  fi

  local uid gid
  uid="$(id -u)"
  gid="$(id -g)"

  docker run -d --rm \
    --name "$name" \
    -u "${uid}:${gid}" \
    -w /work \
    -v "${ws}:/work:rw" \
    --cap-drop=ALL \
    --security-opt=no-new-privileges \
    --pids-limit 256 \
    --memory 2g \
    --cpus 2 \
    "${net_arg[@]}" \
    --label "aichat.sandbox=true" \
    --label "aichat.ttl_minutes=${ttl}" \
    "$image" \
    sh -lc 'sleep infinity' >/dev/null

  printf '{"container":"%s","workspace":"%s","status":"started"}\n' "$name" "$ws" >> "$LLM_OUTPUT"
}

eval "$(argc --argc-eval "$0" "$@")"

