#!/usr/bin/env bash
# Install or remove the shared collector hooks from a mono checkout or the
# self-contained coding-agent-collector-installer archive.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATE="$SCRIPT_DIR/templates/coding-agent-remote-collector.json"
HOOKS_MGR="$SCRIPT_DIR/hooks_mgr.py"
PYTHON_BIN="${PYTHON_BIN:-python3}"
DEST_DIR="$HOME/.collector/bin"
DEST="$DEST_DIR/collector.py"
KEY="${COLLECTOR_PRIVATE_KEY:-$HOME/.collector/id_ed25519}"
KEY_PUB="$KEY.pub"
ACTION=install
AUTO_APPROVE=0
PASSTHROUGH=()

usage() {
    cat <<'EOF'
Usage: bash install-collector.sh [installer options] [hooks-mgr options]

Installer options:
  --remove               Remove only the collector-owned hooks.
  --yes                  Skip confirmation prompts (the key must already be
                         registered before a non-interactive install).
  -h, --help             Show this help.

Hooks-manager options:
  --target claude|codex|pi
                         Limit the operation to one agent (default: all).
  --var url_base=URL     Override the shared collector hook URL.

Environment:
  COLLECTOR_URL_BASE     Collector hook URL; an explicit --var wins.
  COLLECTOR_PRIVATE_KEY Path to the collector signing key.
  OMP_PROFILE/PI_PROFILE
                         Select a named Pi profile.
  PYTHON_BIN             Python 3.10+ executable (default: python3).
EOF
}

while [ "$#" -gt 0 ]; do
    case "$1" in
        --remove)
            ACTION=remove
            shift
            ;;
        --yes)
            AUTO_APPROVE=1
            shift
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        *)
            PASSTHROUGH+=("$1")
            shift
            ;;
    esac
done
set -- "${PASSTHROUGH[@]}"

case "$(uname -s)" in
    Darwin|Linux) ;;
    *)
        echo "error: this installer supports macOS and Linux only" >&2
        exit 1
        ;;
esac

command -v "$PYTHON_BIN" >/dev/null 2>&1 || {
    echo "error: Python 3.10+ is required; '$PYTHON_BIN' was not found" >&2
    exit 1
}
"$PYTHON_BIN" - <<'PY'
import sys

if sys.version_info < (3, 10):
    raise SystemExit(
        f"error: Python 3.10+ is required; found {sys.version.split()[0]}"
    )
PY

[ -f "$TEMPLATE" ] || {
    echo "error: installer template not found: $TEMPLATE" >&2
    exit 1
}
[ -f "$HOOKS_MGR" ] || {
    echo "error: hooks manager not found: $HOOKS_MGR" >&2
    exit 1
}

if [ -f "$SCRIPT_DIR/collector.py" ]; then
    # Layout inside the portable archive.
    SRC="$SCRIPT_DIR/collector.py"
elif [ -f "$SCRIPT_DIR/../coding-agent-control-plane/collector.py" ]; then
    # Layout in the mono checkout.
    SRC="$SCRIPT_DIR/../coding-agent-control-plane/collector.py"
else
    echo "error: collector.py is missing; use the complete installer archive" >&2
    exit 1
fi

pi_agent_dir() {
    local profile="${OMP_PROFILE:-${PI_PROFILE:-}}"
    if [ -n "$profile" ]; then
        case "$profile" in
            */*|.*)
                echo "error: unsafe Pi profile name '$profile'" >&2
                exit 1
                ;;
        esac
        printf '%s/.omp/profiles/%s/agent' "$HOME" "$profile"
    else
        printf '%s/.omp/agent' "$HOME"
    fi
}

PI_AGENT_DIR="$(pi_agent_dir)"
PI_HOOK="$PI_AGENT_DIR/hooks/post/team-collector.js"

hooks_mgr_cmd() {
    local action="$1"
    shift
    if [ -n "${COLLECTOR_URL_BASE:-}" ]; then
        set -- --var "url_base=$COLLECTOR_URL_BASE" "$@"
    fi
    "$PYTHON_BIN" "$HOOKS_MGR" "$action" --template "$TEMPLATE" \
        --var collector="$DEST" \
        --var collector_private_key="$KEY" \
        --var pi_hook_path="$PI_HOOK" \
        "$@"
}

if [ "$ACTION" = remove ]; then
    echo "This removes only hooks owned by the coding-agent collector."
    if [ "$AUTO_APPROVE" -ne 1 ]; then
        read -r -p "Remove the selected collector hooks? [y/N] " ANSWER
        case "$ANSWER" in
            y|Y|yes|YES) ;;
            *)
                echo "aborted — nothing was changed"
                exit 0
                ;;
        esac
    fi
    hooks_mgr_cmd remove "$@"
    echo "done. signing keys and the collector runtime were left in $HOME/.collector"
    exit 0
fi

command -v ssh-keygen >/dev/null 2>&1 || {
    echo "error: OpenSSH ssh-keygen is required" >&2
    exit 1
}

# Put the collector somewhere stable so installed hooks survive the archive or
# checkout being moved or deleted.
mkdir -p "$DEST_DIR"
chmod 700 "$HOME/.collector" "$DEST_DIR"
cp "$SRC" "$DEST"
chmod 700 "$DEST"

SOURCE_LABEL="$SRC"
SOURCE_VERSION=unknown
if [ -f "$SCRIPT_DIR/VERSION" ]; then
    IFS= read -r SOURCE_VERSION < "$SCRIPT_DIR/VERSION" || true
    SOURCE_LABEL="portable installer archive"
elif command -v git >/dev/null 2>&1; then
    SOURCE_VERSION="$(git -C "$SCRIPT_DIR" rev-parse --short HEAD 2>/dev/null || printf unknown)"
fi
{
    echo "copied-from: $SOURCE_LABEL"
    echo "version: ${SOURCE_VERSION:-unknown}"
    echo "installed-at: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
} > "$DEST_DIR/collector.py.source"
chmod 600 "$DEST_DIR/collector.py.source"
echo "collector copied to $DEST"

# Create a collector-specific signing key if one is not already present.
mkdir -p "$(dirname "$KEY")"
chmod 700 "$(dirname "$KEY")"
if [ ! -f "$KEY" ]; then
    ssh-keygen -q -t ed25519 -N "" \
        -C "cacp-collector:${USER:-user}@$(hostname)" \
        -f "$KEY"
    echo "collector signing key created at $KEY"
else
    echo "collector signing key exists at $KEY"
fi
ssh-keygen -y -f "$KEY" > "$KEY_PUB"
chmod 600 "$KEY"
chmod 644 "$KEY_PUB"
FINGERPRINT="$(ssh-keygen -lf "$KEY_PUB" | awk '{print $2}')"

echo
echo "=== Add this public key in the CACP web UI ==="
echo "Open: https://cacp.internal.twodot.ai/keys"
echo "Label: $(hostname) collector"
cat "$KEY_PUB"
echo "Fingerprint: $FINGERPRINT"
echo "============================================="
echo
if [ "$AUTO_APPROVE" -ne 1 ]; then
    read -r -p "Press Enter after the key has been added in the web UI."
fi

echo
echo "=== The following changes would be applied to your live settings ==="
hooks_mgr_cmd diff "$@"
echo "===================================================================="
echo

if [ "$AUTO_APPROVE" -ne 1 ]; then
    read -r -p "Apply these changes? [y/N] " ANSWER
    case "$ANSWER" in
        y|Y|yes|YES) ;;
        *)
            echo "aborted — nothing was changed (the collector copy at $DEST remains)."
            exit 0
            ;;
    esac
fi

hooks_mgr_cmd merge "$@"
echo
echo "done. new agent sessions now report to the configured collector"
echo "verify: your machine appears on the Hosts dashboard at https://grafana.internal.twodot.ai"
echo "undo: bash install-collector.sh --remove"
