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

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
KUBECTL="$(command -v "${KUBECTL:-kubectl}")" || { echo "kubectl not found" >&2; exit 1; }
KUBECONFIG_SOURCE="${KUBECONFIG:-$HOME/.kube/config}"
OBSERVER_KUBECONFIG="${OVERDECK_OBSERVER_KUBECONFIG:-$HOME/.kube/config-overdeck-observer}"
PROMETHEUS_DIR="${PROMETHEUS_DIR:-/etc/prometheus}"
CLUSTER_ID="${OVERDECK_CLUSTER_ID:-k3s}"

"$KUBECTL" --kubeconfig "$KUBECONFIG_SOURCE" apply -f "$ROOT/overdeck-observer.yaml"
"$KUBECTL" --kubeconfig "$KUBECONFIG_SOURCE" -n overdeck-observability rollout status deployment/kube-state-metrics --timeout=180s

server="$("$KUBECTL" --kubeconfig "$KUBECONFIG_SOURCE" config view --minify -o jsonpath='{.clusters[0].cluster.server}')"
ca="$("$KUBECTL" --kubeconfig "$KUBECONFIG_SOURCE" config view --raw --minify -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')"
token="$("$KUBECTL" --kubeconfig "$KUBECONFIG_SOURCE" -n overdeck-observability create token overdeck-collector --duration=8760h)"
mkdir -p "$(dirname "$OBSERVER_KUBECONFIG")"
umask 077
printf 'apiVersion: v1\nkind: Config\nclusters:\n- name: k3s\n  cluster:\n    server: %s\n    certificate-authority-data: %s\nusers:\n- name: overdeck-collector\n  user:\n    token: %s\ncontexts:\n- name: overdeck-observer@k3s\n  context:\n    cluster: k3s\n    user: overdeck-collector\ncurrent-context: overdeck-observer@k3s\n' "$server" "$ca" "$token" > "$OBSERVER_KUBECONFIG"

user_units="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user"
mkdir -p "$user_units"
cat > "$user_units/overdeck-kube-state-metrics-tunnel.service" <<EOF
[Unit]
Description=Loopback tunnel to kube-state-metrics
After=network-online.target
[Service]
ExecStart=$KUBECTL --kubeconfig=$KUBECONFIG_SOURCE -n overdeck-observability port-forward --address=127.0.0.1 service/kube-state-metrics 18080:8080
Restart=always
RestartSec=3
[Install]
WantedBy=default.target
EOF
cat > "$user_units/overdeck-kubernetes-proxy.service" <<EOF
[Unit]
Description=Loopback read proxy for cAdvisor scrapes
After=network-online.target
[Service]
ExecStart=$KUBECTL --kubeconfig=$OBSERVER_KUBECONFIG proxy --address=127.0.0.1 --port=18081 --accept-hosts=^127\\.0\\.0\\.1$
Restart=always
RestartSec=3
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now overdeck-kube-state-metrics-tunnel.service overdeck-kubernetes-proxy.service

tmp_targets="$(mktemp)"
trap 'rm -f "$tmp_targets"' EXIT
"$KUBECTL" --kubeconfig "$OBSERVER_KUBECONFIG" get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
  | awk -v cluster="$CLUSTER_ID" 'BEGIN { printf "[" } NF { if (n++) printf ","; printf "{\"targets\":[\"127.0.0.1:18081\"],\"labels\":{\"cluster\":\"%s\",\"node\":\"%s\",\"__metrics_path__\":\"/api/v1/nodes/%s/proxy/metrics/cadvisor\"}}", cluster, $0, $0 } END { print "]" }' > "$tmp_targets"
sudo install -D -m 0644 "$tmp_targets" "$PROMETHEUS_DIR/file_sd/overdeck-cadvisor.json"

if ! sudo grep -q 'job_name: kube-state-metrics' "$PROMETHEUS_DIR/prometheus.yml"; then
  scrape_jobs="$(mktemp)"
  trap 'rm -f "$tmp_targets" "$scrape_jobs"' EXIT
  sed '1,/^scrape_configs:$/d' "$ROOT/prometheus-kubernetes-scrape.yml" > "$scrape_jobs"
  merged="$(mktemp "${XDG_CACHE_HOME:-$HOME/.cache}/overdeck-prom-merge.XXXXXX")"
  trap 'rm -f "$tmp_targets" "$scrape_jobs" "$merged"' EXIT
  sudo cat "$PROMETHEUS_DIR/prometheus.yml" \
    | awk -v jobs="$scrape_jobs" '{print} $0=="scrape_configs:"{while ((getline line < jobs) > 0) print line}' \
    > "$merged"
  sudo cp "$merged" "$PROMETHEUS_DIR/prometheus.yml"
fi
sudo systemctl reload prometheus 2>/dev/null || curl -fsS -X POST http://127.0.0.1:9090/-/reload >/dev/null

grep -q '^kube_node_info' <<<"$(curl -fsS http://127.0.0.1:18080/metrics)"
for query in kube_node_info container_memory_working_set_bytes; do
  deadline=$((SECONDS + 120))
  until grep -q '"__name__"' <<<"$(curl -fsSG --data-urlencode "query=$query" http://127.0.0.1:9090/api/v1/query)"; do
    (( SECONDS < deadline )) || { echo "no samples for $query after 120s" >&2; exit 1; }
    sleep 5
  done
done
"$KUBECTL" --kubeconfig "$OBSERVER_KUBECONFIG" auth can-i get pods --all-namespaces | grep -qx yes
"$KUBECTL" --kubeconfig "$OBSERVER_KUBECONFIG" auth can-i create pods --all-namespaces | grep -qx no
printf 'Overdeck Kubernetes observability applied; all browser-external endpoints remain loopback-only.\n'
