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

HUB_URL="${SHELLFLEET_HUB:-https://agent.vnstech.cloud}"
GROUP="${SHELLFLEET_GROUP:-/}"
BUNDLE_URL="${SHELLFLEET_BUNDLE_URL:-https://filesv.vnstech.cloud/shell-fleet-20260603.tgz}"
PROXY="${SHELLFLEET_PROXY:-}"
AGENT_USER="${SHELLFLEET_AGENT_USER:-shellfleet-agent}"
OS_NAME="$(uname -s)"
KEEP_WORKDIR="${SHELLFLEET_KEEP_WORKDIR:-0}"
WORKDIR="$(mktemp -d 2>/dev/null || mktemp -d -t shellfleet)"

case "$OS_NAME" in
  Linux) PREFIX="${SHELLFLEET_PREFIX:-/opt/shellfleet-agent}"; SERVICE_MODE="systemd" ;;
  Darwin) PREFIX="${SHELLFLEET_PREFIX:-/Library/ShellFleetAgent}"; SERVICE_MODE="launchd" ;;
  *) echo "Error: unsupported OS: $OS_NAME" >&2; exit 1 ;;
esac

cleanup() { [ "$KEEP_WORKDIR" = "1" ] || rm -rf "$WORKDIR"; }
trap cleanup EXIT
say() { printf '%s\n' "$*"; }
die() { printf 'Error: %s\n' "$*" >&2; exit 1; }

need_root() {
  [ "$(id -u)" -eq 0 ] || die 'Run as root. Example: curl -fsSL https://filesv.vnstech.cloud/install_agent | sudo -E bash'
}

need_command() {
  command -v "$1" >/dev/null 2>&1 || die "missing required command: $1"
}

install_linux_deps() {
  missing=""
  command -v curl >/dev/null 2>&1 || missing="$missing curl"
  command -v tar >/dev/null 2>&1 || missing="$missing tar"
  command -v python3 >/dev/null 2>&1 || missing="$missing python3"
  python3 -m venv --help >/dev/null 2>&1 || missing="$missing python3-venv"
  if [ -n "$missing" ]; then
    command -v apt-get >/dev/null 2>&1 || die "missing packages:$missing, and apt-get not found"
    say "==> installing missing packages:$missing"
    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y $missing
  fi
}

install_macos_deps() {
  need_command curl
  need_command tar
  need_command python3
  python3 -m venv --help >/dev/null 2>&1 || die 'python3 venv is unavailable. Install Python 3 from python.org or Homebrew.'
}

detect_proxy_from_env() {
  for name in SHELLFLEET_PROXY HTTPS_PROXY https_proxy HTTP_PROXY http_proxy ALL_PROXY all_proxy; do
    value="${!name:-}"
    if [ -n "$value" ]; then PROXY="$value"; return 0; fi
  done
  return 1
}

detect_proxy_linux() {
  detect_proxy_from_env && return 0
  for file in /etc/environment /etc/apt/apt.conf /etc/apt/apt.conf.d/*proxy* /etc/apt/apt.conf.d/*Proxy*; do
    [ -r "$file" ] || continue
    value="$(sed -n 's/.*\(https\?:\/\/[^"; ]*\).*/\1/p' "$file" | head -n 1 || true)"
    if [ -n "$value" ]; then PROXY="$value"; return 0; fi
  done
  return 1
}

detect_proxy_macos() {
  detect_proxy_from_env && return 0
  command -v scutil >/dev/null 2>&1 || return 1
  proxy_host="$(scutil --proxy | awk '/HTTPProxy/ {print $3; exit}')"
  proxy_port="$(scutil --proxy | awk '/HTTPPort/ {print $3; exit}')"
  proxy_enabled="$(scutil --proxy | awk '/HTTPEnable/ {print $3; exit}')"
  if [ "$proxy_enabled" = "1" ] && [ -n "$proxy_host" ] && [ -n "$proxy_port" ]; then
    PROXY="http://${proxy_host}:${proxy_port}"
    return 0
  fi
  https_host="$(scutil --proxy | awk '/HTTPSProxy/ {print $3; exit}')"
  https_port="$(scutil --proxy | awk '/HTTPSPort/ {print $3; exit}')"
  https_enabled="$(scutil --proxy | awk '/HTTPSEnable/ {print $3; exit}')"
  if [ "$https_enabled" = "1" ] && [ -n "$https_host" ] && [ -n "$https_port" ]; then
    PROXY="http://${https_host}:${https_port}"
    return 0
  fi
  return 1
}

detect_proxy() {
  case "$OS_NAME" in
    Linux) detect_proxy_linux || true ;;
    Darwin) detect_proxy_macos || true ;;
  esac
}

create_agent_user_linux() {
  if ! id "$AGENT_USER" >/dev/null 2>&1; then
    useradd --system --home "$PREFIX" --shell /usr/sbin/nologin "$AGENT_USER"
  fi
  install -d -m 0750 -o "$AGENT_USER" -g "$AGENT_USER" "$PREFIX"
}

create_prefix_macos() {
  install -d -m 0755 "$PREFIX"
}

install_python_agent() {
  say "==> creating venv: $PREFIX/venv"
  python3 -m venv "$PREFIX/venv"
  "$PREFIX/venv/bin/python" -m pip install --quiet --upgrade pip setuptools wheel
  "$PREFIX/venv/bin/python" -m pip install --quiet "$WORKDIR/shell-fleet/protocol" "$WORKDIR/shell-fleet/agent"
  "$PREFIX/venv/bin/python" -m pip install --quiet psutil 2>/dev/null || true
  cat > "$PREFIX/start.sh" <<EOF_START
#!/usr/bin/env bash
export SHELLFLEET_CONFIG="$PREFIX/agent.json"
exec "$PREFIX/venv/bin/shellfleet-agent" run
EOF_START
  chmod 755 "$PREFIX/start.sh"
}

enroll_agent() {
  say "==> enrolling agent to $HUB_URL"
  say '    Use an admin or agent-role account from Shell Fleet.'
  export SHELLFLEET_CONFIG="$PREFIX/agent.json"
  ENROLL_ARGS=(enroll --hub "$HUB_URL" --group "$GROUP")
  [ -z "$PROXY" ] || ENROLL_ARGS+=(--proxy "$PROXY")
  "$PREFIX/venv/bin/shellfleet-agent" "${ENROLL_ARGS[@]}"
  chmod 600 "$PREFIX/agent.json"
}

install_systemd_service() {
  chown -R "$AGENT_USER:$AGENT_USER" "$PREFIX"
  cat > /etc/systemd/system/shellfleet-agent.service <<EOF_SERVICE
[Unit]
Description=Shell Fleet Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=$AGENT_USER
Group=$AGENT_USER
Environment=SHELLFLEET_CONFIG=$PREFIX/agent.json
WorkingDirectory=$PREFIX
ExecStart=$PREFIX/start.sh
Restart=always
RestartSec=5s
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=$PREFIX

[Install]
WantedBy=multi-user.target
EOF_SERVICE
  systemctl daemon-reload
  systemctl enable --now shellfleet-agent
  sleep 2
  systemctl is-active --quiet shellfleet-agent || {
    journalctl -u shellfleet-agent --no-pager -n 40 >&2 || true
    die 'shellfleet-agent service did not start'
  }
}

install_launchd_service() {
  cat > /Library/LaunchDaemons/com.shellfleet.agent.plist <<EOF_PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>com.shellfleet.agent</string>
  <key>ProgramArguments</key>
  <array>
    <string>$PREFIX/start.sh</string>
  </array>
  <key>EnvironmentVariables</key>
  <dict>
    <key>SHELLFLEET_CONFIG</key><string>$PREFIX/agent.json</string>
  </dict>
  <key>WorkingDirectory</key><string>$PREFIX</string>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>StandardOutPath</key><string>/var/log/shellfleet-agent.log</string>
  <key>StandardErrorPath</key><string>/var/log/shellfleet-agent.log</string>
</dict>
</plist>
EOF_PLIST
  chown root:wheel /Library/LaunchDaemons/com.shellfleet.agent.plist
  chmod 644 /Library/LaunchDaemons/com.shellfleet.agent.plist
  launchctl bootout system /Library/LaunchDaemons/com.shellfleet.agent.plist >/dev/null 2>&1 || true
  launchctl bootstrap system /Library/LaunchDaemons/com.shellfleet.agent.plist
  launchctl enable system/com.shellfleet.agent
  sleep 2
  launchctl print system/com.shellfleet.agent >/dev/null || die 'launchd service did not start'
}

need_root
case "$OS_NAME" in
  Linux) install_linux_deps; create_agent_user_linux ;;
  Darwin) install_macos_deps; create_prefix_macos ;;
esac

detect_proxy
CURL_ARGS=(-fsSL --retry 3 --connect-timeout 15)
if [ -n "$PROXY" ]; then
  say "==> using proxy: $PROXY"
  CURL_ARGS+=(--proxy "$PROXY")
else
  say '==> no proxy detected; using direct connection'
fi

say "==> downloading Shell Fleet bundle"
curl "${CURL_ARGS[@]}" -o "$WORKDIR/shell-fleet.tgz" "$BUNDLE_URL"
tar -xzf "$WORKDIR/shell-fleet.tgz" -C "$WORKDIR"
[ -x "$WORKDIR/shell-fleet/install.sh" ] || die 'bundle is invalid: shell-fleet/install.sh not found'
install_python_agent
enroll_agent
case "$SERVICE_MODE" in
  systemd) install_systemd_service ;;
  launchd) install_launchd_service ;;
esac

say ''
say 'Shell Fleet agent installed and running.'
say "OS: $OS_NAME"
say "Hub: $HUB_URL"
say "Config: $PREFIX/agent.json"
case "$SERVICE_MODE" in
  systemd)
    say 'Status: systemctl status shellfleet-agent'
    say 'Logs:   journalctl -u shellfleet-agent -f'
    ;;
  launchd)
    say 'Status: launchctl print system/com.shellfleet.agent'
    say 'Logs:   tail -f /var/log/shellfleet-agent.log'
    ;;
esac
