#!/usr/bin/env bash
# Sync Keycloak users into Gitea local accounts (for CLI + tokens).
# Requires: curl, jq, kubectl. Expects a Keycloak client with realm-management
# permissions (manage-users) and a Gitea admin token stored in a secret.

set -euo pipefail

require() { command -v "$1" >/dev/null 2>&1 || { echo "missing required binary: $1" >&2; exit 1; }; }
require curl; require jq; require kubectl

: "${KEYCLOAK_URL:=https://sso.bstein.dev}"
: "${KEYCLOAK_REALM:=atlas}"
: "${KEYCLOAK_CLIENT_ID:?set KEYCLOAK_CLIENT_ID or export via secret}"
: "${KEYCLOAK_CLIENT_SECRET:?set KEYCLOAK_CLIENT_SECRET or export via secret}"
: "${GITEA_BASE_URL:=https://scm.bstein.dev}"
: "${GITEA_NAMESPACE:=gitea}"
: "${GITEA_TOKEN_SECRET_NAME:=gitea-admin-token}"
: "${GITEA_TOKEN_SECRET_KEY:=token}"
: "${DEFAULT_PASSWORD:=TempSsoPass!2025}"

fetch_token() {
  curl -fsS -X POST \
    -d "grant_type=client_credentials" \
    -d "client_id=${KEYCLOAK_CLIENT_ID}" \
    -d "client_secret=${KEYCLOAK_CLIENT_SECRET}" \
    "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \
    | jq -r '.access_token'
}

pull_users() {
  local token="$1"
  curl -fsS -H "Authorization: Bearer ${token}" \
    "${KEYCLOAK_URL}/admin/realms/${KEYCLOAK_REALM}/users?max=500" \
    | jq -r '.[] | select(.enabled == true) | select(.username | startswith("service-account-") | not) | [.username, (.email // ""), (.firstName // ""), (.lastName // "")] | @tsv'
}

get_gitea_token() {
  if [[ -n "${GITEA_ADMIN_TOKEN:-}" ]]; then
    echo "${GITEA_ADMIN_TOKEN}"
    return
  fi
  kubectl -n "${GITEA_NAMESPACE}" get secret "${GITEA_TOKEN_SECRET_NAME}" -o "jsonpath={.data.${GITEA_TOKEN_SECRET_KEY}}" \
    | base64 -d
}

user_exists() {
  local token="$1" username="$2"
  local code
  code=$(curl -s -o /dev/null -w '%{http_code}' \
    -H "Authorization: token ${token}" \
    "${GITEA_BASE_URL}/api/v1/admin/users/${username}")
  [[ "${code}" == "200" ]]
}

create_user() {
  local token="$1" username="$2" email="$3" fname="$4" lname="$5"
  local body status fullname
  fullname="$(echo "${fname} ${lname}" | xargs)"
  if [[ -z "${email}" ]]; then
    email="${username}@example.local"
  fi
  body=$(jq -n --arg u "${username}" --arg e "${email}" --arg p "${DEFAULT_PASSWORD}" \
    --arg fn "${fullname}" '{username:$u, email:$e, password:$p, must_change_password:false, full_name:$fn}')
  status=$(curl -s -o /dev/null -w '%{http_code}' \
    -H "Authorization: token ${token}" \
    -H "Content-Type: application/json" \
    -X POST \
    -d "${body}" \
    "${GITEA_BASE_URL}/api/v1/admin/users")
  if [[ "${status}" == "201" ]]; then
    echo "created gitea user ${username}"
  elif [[ "${status}" == "409" ]]; then
    echo "gitea user ${username} already exists (409)" >&2
  else
    echo "failed to create gitea user ${username} (status ${status})" >&2
  fi
}

main() {
  local kc_token gitea_token
  kc_token="$(fetch_token)"
  gitea_token="$(get_gitea_token)"

  while IFS=$'\t' read -r username email fname lname; do
    if user_exists "${gitea_token}" "${username}"; then
      continue
    fi
    create_user "${gitea_token}" "${username}" "${email}" "${fname}" "${lname}"
  done < <(pull_users "${kc_token}")
}

main "$@"
