#!/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:-}"
PROXY_SOURCE=""
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

if [ -t 1 ]; then
  RESET='\033[0m'; BOLD='\033[1m'; DIM='\033[2m'
  CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; BLUE='\033[34m'
else
  RESET=''; BOLD=''; DIM=''; CYAN=''; GREEN=''; YELLOW=''; RED=''; BLUE=''
fi

cleanup() { [ "$KEEP_WORKDIR" = "1" ] || rm -rf "$WORKDIR"; }
trap cleanup EXIT
say() { printf '%b\n' "$*"; }
step() { say "${BLUE}${BOLD}==>${RESET} ${BOLD}$*${RESET}"; }
ok() { say "${GREEN}✓${RESET} $*"; }
warn() { say "${YELLOW}!${RESET} $*"; }
die() { say "${RED}✗ Error:${RESET} $*" >&2; exit 1; }

banner() {
  say "${CYAN}${BOLD}+----------------------------------------------------------+${RESET}"
  say "${CYAN}${BOLD}|              Shell Fleet Agent Installer                  |${RESET}"
  say "${CYAN}${BOLD}+----------------------------------------------------------+${RESET}"
  say "${DIM}  OS    : $OS_NAME${RESET}"
  say "${DIM}  Hub   : $HUB_URL${RESET}"
  say "${DIM}  Group : $GROUP${RESET}"
  say "${DIM}  Prefix: $PREFIX${RESET}"
  printf '\n'
}

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"
    step "Installing missing packages:$missing"
    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y $missing
  else
    ok 'Required Linux packages are present.'
  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.'
  ok 'Required macOS commands are present.'
}

set_proxy() {
  PROXY="$1"; PROXY_SOURCE="$2"; return 0
}

proxy_from_env() {
  for name in SHELLFLEET_PROXY HTTPS_PROXY https_proxy HTTP_PROXY http_proxy ALL_PROXY all_proxy; do
    value="${!name:-}"
    [ -n "$value" ] && set_proxy "$value" "env:$name" && return 0
  done
  return 1
}

proxy_from_apt_files() {
  for file in /etc/apt/apt.conf /etc/apt/apt.conf.d/* /etc/environment; do
    [ -r "$file" ] || continue
    value="$({
      sed -nE 's/^[[:space:]]*Acquire::(https?|HTTPS?)::Proxy[[:space:]]+"([^"]+)";.*/\2/p' "$file"
      sed -nE "s/^[[:space:]]*Acquire::(https?|HTTPS?)::Proxy[[:space:]]+'([^']+)';.*/\2/p" "$file"
      sed -nE 's/^[[:space:]]*(https?|HTTPS?)_proxy=("?)([^"[:space:]]+)\2.*/\3/p' "$file"
      sed -nE 's/^[[:space:]]*(HTTPS?|https?)_PROXY=("?)([^"[:space:]]+)\2.*/\3/p' "$file"
    } | grep -E '^https?://' | grep -vi 'DIRECT' | head -n 1 || true)"
    [ -n "$value" ] && set_proxy "$value" "apt:$file" && return 0
  done
  return 1
}

proxy_from_macos_scutil() {
  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
    set_proxy "http://${proxy_host}:${proxy_port}" 'macos:scutil HTTP'; 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
    set_proxy "http://${https_host}:${https_port}" 'macos:scutil HTTPS'; return 0
  fi
  return 1
}

detect_proxy() {
  step 'Detecting outbound proxy'
  if [ -n "${SHELLFLEET_PROXY:-}" ]; then
    set_proxy "$SHELLFLEET_PROXY" 'env:SHELLFLEET_PROXY'
  elif [ "$OS_NAME" = "Linux" ]; then
    proxy_from_apt_files || proxy_from_env || true
  else
    proxy_from_env || proxy_from_macos_scutil || true
  fi
  if [ -n "$PROXY" ]; then ok "Using proxy from $PROXY_SOURCE: $PROXY"; else warn 'No proxy detected; using direct connection.'; fi
}

create_agent_user_linux() {
  if ! id "$AGENT_USER" >/dev/null 2>&1; then
    useradd --system --home "$PREFIX" --shell /usr/sbin/nologin "$AGENT_USER"
    ok "Created system user $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() {
  step "Creating Python environment at $PREFIX/venv"
  python3 -m venv "$PREFIX/venv"
  "$PREFIX/venv/bin/python" -m pip install --quiet --upgrade pip setuptools wheel
  step 'Installing Shell Fleet agent packages'
  "$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() {
  step "Enrolling agent to $HUB_URL"
  say "${DIM}Use an admin or agent-role Shell Fleet account.${RESET}"
  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() {
  step 'Installing 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'
  }
  ok 'systemd service is running.'
}

install_launchd_service() {
  step 'Installing macOS LaunchDaemon'
  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'
  ok 'LaunchDaemon is running.'
}

banner
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)
[ -z "$PROXY" ] || CURL_ARGS+=(--proxy "$PROXY")
step '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'
ok 'Bundle downloaded and verified.'
install_python_agent
enroll_agent
case "$SERVICE_MODE" in
  systemd) install_systemd_service ;;
  launchd) install_launchd_service ;;
esac

printf '\n'
say "${GREEN}${BOLD}Shell Fleet agent installed and running.${RESET}"
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
