#!/usr/bin/env bash
# scripts/onboard/lib/common.sh — shared helpers for the onboarding tool

set -euo pipefail

# ── colour codes (disabled when not a tty) ──────────────────────────────────
if [[ -t 1 ]]; then
    _C_RESET='\033[0m'
    _C_GREEN='\033[0;32m'
    _C_YELLOW='\033[1;33m'
    _C_RED='\033[0;31m'
    _C_CYAN='\033[0;36m'
    _C_BOLD='\033[1m'
else
    _C_RESET='' _C_GREEN='' _C_YELLOW='' _C_RED='' _C_CYAN='' _C_BOLD=''
fi

# ── logging ──────────────────────────────────────────────────────────────────
log()  { echo -e "${_C_GREEN}[onboard]${_C_RESET} $(date +'%H:%M:%S') ${*}"; }
warn() { echo -e "${_C_YELLOW}[WARN]${_C_RESET}    $(date +'%H:%M:%S') ${*}" >&2; }
die()  { echo -e "${_C_RED}[ERROR]${_C_RESET}   $(date +'%H:%M:%S') ${*}" >&2; exit 1; }
step() { echo -e "${_C_CYAN}${_C_BOLD}==> ${*}${_C_RESET}"; }
dryrun() { echo -e "${_C_YELLOW}[dry-run]${_C_RESET} ${*}"; }

# ── command detection ─────────────────────────────────────────────────────────
have_cmd() { command -v "$1" >/dev/null 2>&1; }

# ── dry-run execution wrapper ─────────────────────────────────────────────────
# run CMD [ARGS…] — executes CMD in live mode; prints intent in dry-run.
# Wrap MUTATIONS with this. Read-only probes (SSH BatchMode tests, status
# queries, command -v checks) must run unconditionally — never wrap them.
run() {
    if [ "${DRY_RUN:-0}" = 1 ]; then
        echo "[dry-run] would: $*"
    else
        "$@"
    fi
}
export -f run

# ── file helpers ──────────────────────────────────────────────────────────────
# ensure_line FILE LINE — appends LINE to FILE if it is not already present (idempotent)
ensure_line() {
    local file="$1" line="$2"
    [[ -f "$file" ]] || touch "$file"
    grep -qxF "$line" "$file" || echo "$line" >> "$file"
}

# ── node.yaml parsing ─────────────────────────────────────────────────────────
# require_node_yaml NODE — sets NODE_YAML; exits if not found
require_node_yaml() {
    local node="$1"
    NODE_YAML="${REPO_ROOT}/hosts/${node,,}/node.yaml"
    [[ -f "$NODE_YAML" ]] || die "node.yaml not found: $NODE_YAML"
    export NODE_YAML
}

# yaml_get NODE_YAML KEY — read a scalar value from a YAML file
# Uses yq when available; falls back to grep/sed for simple key: value pairs.
# Supports dot-separated paths (e.g. tailscale.hostname) only in yq mode;
# the grep fallback handles only the last path component.
yaml_get() {
    local file="$1" key="$2"
    if have_cmd yq; then
        yq -r ".${key} // empty" "$file" 2>/dev/null
    else
        # fallback: extract last segment of key, match "  key: value"
        # Strip inline YAML comment (space(s)+'#'+rest) and surrounding whitespace.
        # Pattern uses \+ (BRE one-or-more) so a bare '#' inside a value is preserved.
        local leaf="${key##*.}"
        grep -E "^\s*${leaf}:" "$file" | head -1 \
            | sed -e 's/^[[:space:]]*[^:]*:[[:space:]]*//' \
                  -e 's/[[:space:]]\+#.*$//' \
                  -e 's/^[[:space:]]*//' \
                  -e 's/[[:space:]]*$//' \
            | tr -d '"' | tr -d "'"
    fi
}

# ── git wrapper ────────────────────────────────────────────────────────────────
# All git calls from onboarding scripts must go through this so --no-pager is
# always set and there is no interactive output.
git() { command git --no-pager "$@"; }
export -f git
