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

# Sandbox wrapper for Microsoft Fabric CLI.
# Keeps Fabric CLI config/cache out of the repo and read-only home.
# Never use this wrapper for production.
#
# Tested against: ms-fabric-cli >= 0.1.0
# Run 'tool/setup/setup.sh' to see the installed version.

FAB_MIN_VERSION="${FAB_MIN_VERSION:-0.1.0}"
_USER_HOME="$(python3 -c 'import os,pwd; print(pwd.getpwuid(os.getuid()).pw_dir)' 2>/dev/null || true)"
if [[ -z "${_USER_HOME}" || ! -d "${_USER_HOME}" ]]; then
    echo "Could not resolve the current user's home directory." >&2
    exit 1
fi

# ── Validate externally supplied overrides before applying defaults (H-05) ─────
if [[ -n "${FAB_SANDBOX_HOME:-}" ]]; then
    [[ "${FAB_SANDBOX_HOME}" = /* ]] || { echo "FAB_SANDBOX_HOME must be an absolute path." >&2; exit 1; }
    [[ "${FAB_SANDBOX_HOME}" = "${_USER_HOME}/"* || "${FAB_SANDBOX_HOME}" = "${_USER_HOME}" ]] || \
        { echo "FAB_SANDBOX_HOME must be within the current user's home directory." >&2; exit 1; }
fi

# Default to a user-owned path instead of world-writable /tmp (H-03: prevents TOCTOU symlink attacks)
FAB_SANDBOX_HOME="${FAB_SANDBOX_HOME:-${_USER_HOME}/.local/state/fabric-fab-home}"

_fab_bin="${_USER_HOME}/.local/bin/fab"
if [[ ! -x "${_fab_bin}" ]]; then
  echo "fab executable not found at ${_fab_bin}. Install with: uv tool install ms-fabric-cli" >&2
  exit 127
fi

# Assert minimum version
_fab_version="$("${_fab_bin}" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)"
if [[ -n "${_fab_version}" ]]; then
  _ok=$(python3 -c "
import sys
try:
    from packaging.version import Version
    print('yes' if Version(sys.argv[1]) >= Version(sys.argv[2]) else 'no')
except Exception:
    print('yes')
" "${_fab_version}" "${FAB_MIN_VERSION}" 2>/dev/null || echo "yes")
  if [[ "${_ok}" == "no" ]]; then
    echo "fab version ${_fab_version} is below minimum required ${FAB_MIN_VERSION}." >&2
    echo "Upgrade with: uv tool install --upgrade ms-fabric-cli" >&2
    exit 1
  fi
fi

# Load the three Fabric config vars from .env (two levels up from this script's directory).
# FABRIC_CLIENT_SECRET is intentionally excluded — it must come from the OS environment only.
_load_env_var() {
  local key="$1" repo_root="$2"
  local val
  val=$(grep -E "^${key}\s*=" "${repo_root}/.env" 2>/dev/null | tail -1 | cut -d= -f2- | sed 's/#.*//' | xargs)
  if [[ -n "$val" ]]; then export "$key"="$val"; fi
}
_REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
if [[ -f "${_REPO_ROOT}/.env" ]]; then
  _load_env_var "FABRIC_WORKSPACE_ID" "${_REPO_ROOT}"
  _load_env_var "FABRIC_CLIENT_ID"    "${_REPO_ROOT}"
  _load_env_var "FABRIC_TENANT_ID"    "${_REPO_ROOT}"
fi

# Map SPN credentials to Azure SDK environment variable names so fab CLI
# can authenticate via EnvironmentCredential without a cached token.
if [[ -n "${FABRIC_CLIENT_ID:-}" && -n "${FABRIC_CLIENT_SECRET:-}" && -n "${FABRIC_TENANT_ID:-}" ]]; then
  export AZURE_CLIENT_ID="${FABRIC_CLIENT_ID}"
  export AZURE_CLIENT_SECRET="${FABRIC_CLIENT_SECRET}"
  export AZURE_TENANT_ID="${FABRIC_TENANT_ID}"
fi

mkdir -p "${FAB_SANDBOX_HOME}"
export HOME="${FAB_SANDBOX_HOME}"

exec "${_fab_bin}" "$@"
