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

script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
repo_root=$(git -C "$script_dir" rev-parse --show-toplevel)
helm_bin=${HELM:-helm}
kubectl_bin=${KUBECTL:-kubectl}
token_path=${GITHUB_CHECKS_TOKEN_PATH:-$HOME/.config/overdeck/github-checks.token}
cache_root=${XDG_CACHE_HOME:-$HOME/.cache}/overdeck/arc-charts
chart_version=0.14.2
controller_chart=gha-runner-scale-set-controller-${chart_version}.tgz
runner_chart=gha-runner-scale-set-${chart_version}.tgz
controller_sha=222763b7edbe57eabe626cda09bb58040ed9c70471d32aab650c8e6825a3d8e7
runner_sha=1a2d104e55486cad373a9c33f3cefd0b268cd567743e57ea5da8e1ddf75e0cc0

[[ -x "$(command -v "$helm_bin" 2>/dev/null || true)" ]] || {
  printf 'install-arc: Helm is required (set HELM to the pinned binary)\n' >&2
  exit 2
}
[[ -x "$(command -v "$kubectl_bin" 2>/dev/null || true)" ]] || {
  printf 'install-arc: kubectl is required\n' >&2
  exit 2
}
[[ -s "$token_path" ]] || {
  printf 'install-arc: GitHub token missing at %s\n' "$token_path" >&2
  exit 2
}
mode=$(stat -c '%a' "$token_path")
(( (8#$mode & 8#077) == 0 )) || {
  printf 'install-arc: GitHub token must not be group/world accessible: %s mode=%s\n' "$token_path" "$mode" >&2
  exit 2
}
LC_ALL=C token=$(<"$token_path")
token_bytes=$(wc -c < "$token_path")
[[ -n "$token" && ${#token} -eq token_bytes && "$token" != *[[:space:]]* ]] || {
  printf 'install-arc: GitHub token must be non-empty with no whitespace or trailing newline: %s\n' "$token_path" >&2
  exit 2
}
unset token token_bytes

mkdir -p "$cache_root"
fetch_chart() {
  local name=$1 expected=$2
  local archive="$cache_root/$name"
  if [[ ! -f "$archive" ]]; then
    "$helm_bin" pull "oci://ghcr.io/actions/actions-runner-controller-charts/${name%-${chart_version}.tgz}" \
      --version "$chart_version" --destination "$cache_root"
  fi
  printf '%s  %s\n' "$expected" "$archive" | sha256sum --check --status || {
    printf 'install-arc: chart checksum mismatch: %s\n' "$archive" >&2
    exit 3
  }
}

fetch_chart "$controller_chart" "$controller_sha"
fetch_chart "$runner_chart" "$runner_sha"

"$kubectl_bin" apply \
  -f "$repo_root/modules/ci/k8s/namespace.yaml" \
  -f "$repo_root/modules/ci/k8s/pnpm-store.yaml" \
  -f "$repo_root/modules/ci/k8s/network-policy.yaml"

"$kubectl_bin" -n arc-ci create secret generic arc-github-config \
  --from-file=github_token="$token_path" \
  --dry-run=client -o yaml | "$kubectl_bin" apply -f - >/dev/null

"$helm_bin" upgrade --install arc-controller "$cache_root/$controller_chart" \
  --namespace arc-systems --create-namespace \
  --values "$repo_root/modules/ci/arc/controller-values.yaml" \
  --wait --timeout 5m

"$helm_bin" upgrade --install arc-k3s "$cache_root/$runner_chart" \
  --namespace arc-ci \
  --values "$repo_root/modules/ci/arc/runner-values.yaml" \
  --wait --timeout 5m

"$kubectl_bin" -n arc-systems rollout status deployment/arc-controller-gha-rs-controller --timeout=180s
"$kubectl_bin" -n arc-systems wait --for=condition=Ready pod -l actions.github.com/scale-set-name=arc-k3s --timeout=180s

# Applied last, not with the other manifests: it lives in arc-systems, and that
# namespace only exists once the controller chart has created it above.
"$kubectl_bin" apply -f "$repo_root/modules/ci/k8s/listener-watchdog.yaml"
