#!/usr/bin/env bash
# Monoceros devcontainer feature: gitlab-cli.
#
# Installs the official GitLab CLI (`glab`) from the project's release
# artifacts on gitlab.com — deliberately NOT the distro apt package,
# which lags far behind (often ~a year). The version to install is
# resolved at build time: `latest` asks the GitLab release API for the
# newest tag; a pinned `version` installs exactly that. `monoceros
# upgrade` rebuilds and re-fetches, so the tool stays current (ADR 0018).
#
# Auth is via the GITLAB_TOKEN / GITLAB_HOST environment variables, which
# glab reads directly — so when `apiToken` (and optionally `host`) are
# set, a /etc/profile.d snippet is enough and no `glab auth login` step
# is needed. Config/login state lives at ~/.config/glab-cli, bind-mounted
# from the host so it survives apply rebuilds.

set -euo pipefail

VERSION="${VERSION:-latest}"
APITOKEN="${APITOKEN:-}"
HOST="${HOST:-}"

ARCH="$(dpkg --print-architecture)"
case "${ARCH}" in
  amd64 | arm64) ;;
  *)
    echo "[gitlab-cli] unsupported architecture: ${ARCH}" >&2
    exit 1
    ;;
esac

# Resolve the release tag. `latest` → newest tag from the GitLab release
# API; otherwise normalise the pinned value to a `v`-prefixed tag.
if [ "${VERSION}" = "latest" ]; then
  echo "[gitlab-cli] resolving latest release from gitlab.com"
  TAG="$(curl -fsSL 'https://gitlab.com/api/v4/projects/gitlab-org%2Fcli/releases/permalink/latest' | jq -r '.tag_name')"
  if [ -z "${TAG}" ] || [ "${TAG}" = "null" ]; then
    echo "[gitlab-cli] ERROR: could not resolve the latest glab release" >&2
    exit 1
  fi
else
  TAG="v${VERSION#v}"
fi
VER="${TAG#v}"

URL="https://gitlab.com/gitlab-org/cli/-/releases/${TAG}/downloads/glab_${VER}_linux_${ARCH}.tar.gz"
echo "[gitlab-cli] downloading glab ${VER} for ${ARCH}"
TMP="$(mktemp -d)"
curl -fsSL -o "${TMP}/glab.tar.gz" "${URL}"
tar -xzf "${TMP}/glab.tar.gz" -C "${TMP}"

# Locate the binary in the tarball rather than assuming its layout. `-quit`
# rather than `| head -n1`, which stops the walk at the first hit instead of
# relying on `head` to close the pipe: under `pipefail` the exit status of a
# producer that loses that race would fail the assignment, and `set -e` would
# take the feature down with no output. Not a bug you can trigger here (find
# dies of SIGPIPE, and even 4000 matches finish writing before head exits), but
# the same shape that did take the atlassian feature down, where the producer
# was a Node CLI and Node reports the closed pipe as exit 1.
BIN="$(find "${TMP}" -type f -name glab -print -quit)"
if [ -z "${BIN}" ]; then
  echo "[gitlab-cli] ERROR: glab binary not found in the release tarball" >&2
  exit 1
fi
install -o root -g root -m 0755 "${BIN}" /usr/local/bin/glab
rm -rf "${TMP}"

glab --version >/dev/null 2>&1 || {
  echo "[gitlab-cli] ERROR: install completed but \`glab\` is not on PATH" >&2
  exit 1
}

# Auth/config via environment (glab reads GITLAB_TOKEN / GITLAB_HOST
# directly). We write the profile.d snippet when there is anything to
# export: a token, a host, or both.
if [ -n "${APITOKEN}" ] || [ -n "${HOST}" ]; then
  {
    echo "# Auto-generated by the Monoceros gitlab-cli feature."
    if [ -n "${APITOKEN}" ]; then
      echo "export GITLAB_TOKEN='${APITOKEN}'"
    fi
    if [ -n "${HOST}" ]; then
      echo "export GITLAB_HOST='${HOST}'"
    fi
  } >/etc/profile.d/gitlab-cli.sh
  chmod 0644 /etc/profile.d/gitlab-cli.sh
fi

if [ -n "${APITOKEN}" ]; then
  echo "[gitlab-cli] apiToken wired via /etc/profile.d/ → \`glab\` authenticated in login shells"
else
  echo "[gitlab-cli] no apiToken set — run \`glab auth login\` once in the container; auth state persists under ~/.config/glab-cli"
fi

echo "[gitlab-cli] done"
