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

readonly PLUGIN_URL='https://gerrit-ci.gerritforge.com/job/plugin-code-owners-bazel-stable-3.14/6/artifact/bazel-bin/plugins/code-owners/code-owners.jar'
readonly PLUGIN_SHA256='3d7f275efcee227eee8d5b6ae3cb564d62e4b9f4a3981666c868ce81bdb1a9f7'
readonly PLUGIN_PATH='/var/gerrit/plugins/code-owners.jar'
readonly ALLOWED_EMAIL_DOMAIN="${ALLOWED_EMAIL_DOMAIN:-example.internal}"

if [[ ! $ALLOWED_EMAIL_DOMAIN =~ ^[A-Za-z0-9.-]+$ ]]; then
  echo 'ALLOWED_EMAIL_DOMAIN contains unsupported characters.' >&2
  exit 1
fi

for command in curl docker sha256sum; do
  if ! command -v "$command" >/dev/null 2>&1; then
    echo "Required command not found: $command" >&2
    exit 1
  fi
done

if ! docker compose ps --status running --services | grep -qx gerrit; then
  echo 'The Gerrit Compose service is not running.' >&2
  exit 1
fi

temporary_jar=$(mktemp)
trap 'rm -f "$temporary_jar"' EXIT

curl --fail --location --silent --show-error \
  --retry 3 --retry-all-errors \
  "$PLUGIN_URL" \
  --output "$temporary_jar"

actual_checksum=$(sha256sum "$temporary_jar" | awk '{print $1}')
if [[ $actual_checksum != "$PLUGIN_SHA256" ]]; then
  echo "Code Owners checksum mismatch: $actual_checksum" >&2
  exit 1
fi

# Opt out every project before Gerrit can discover the plugin JAR.
docker compose exec -T \
  -e ALLOWED_EMAIL_DOMAIN="$ALLOWED_EMAIL_DOMAIN" \
  gerrit sh -eu -c '
config=/var/gerrit/etc/gerrit.config
backup="${config}.before-code-owners"

cp -p "$config" "$backup"
git config -f "$config" plugin.code-owners.disabled true
git config -f "$config" plugin.code-owners.backend find-owners
git config -f "$config" plugin.code-owners.requiredApproval Code-Review+1
git config -f "$config" plugin.code-owners.overrideApproval Owners-Override+1
git config -f "$config" plugin.code-owners.fallbackCodeOwners NONE
git config -f "$config" plugin.code-owners.enableImplicitApprovals FALSE
git config -f "$config" plugin.code-owners.mergeCommitStrategy ALL_CHANGED_FILES
git config -f "$config" --unset-all plugin.code-owners.allowedEmailDomain || true
git config -f "$config" --add plugin.code-owners.allowedEmailDomain "$ALLOWED_EMAIL_DOMAIN"
'

docker compose exec -T gerrit sh -eu -c '
temporary_path=/var/gerrit/plugins/.code-owners.jar.tmp
trap '\''rm -f "$temporary_path"'\'' EXIT
cat > "$temporary_path"
chmod 0644 "$temporary_path"
mv "$temporary_path" /var/gerrit/plugins/code-owners.jar
trap - EXIT
' < "$temporary_jar"

docker compose restart gerrit >/dev/null

health=''
ready=false
for _ in $(seq 1 90); do
  container_id=$(docker compose ps -q gerrit 2>/dev/null || true)
  if [[ -n $container_id ]]; then
    health=$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container_id" 2>/dev/null || true)
    if [[ $health == healthy || $health == running ]] &&
      docker compose exec -T gerrit curl --fail --silent http://localhost:8080/config/server/version >/dev/null 2>&1; then
      ready=true
      break
    fi
  fi
  sleep 2
done

if [[ $ready != true ]]; then
  docker compose logs --tail 100 gerrit >&2
  echo "Gerrit did not become ready after installing Code Owners: ${health:-unknown}" >&2
  exit 1
fi

installed_checksum=$(docker compose exec -T gerrit sha256sum "$PLUGIN_PATH" | awk '{print $1}')
if [[ $installed_checksum != "$PLUGIN_SHA256" ]]; then
  echo "Installed Code Owners checksum mismatch: $installed_checksum" >&2
  exit 1
fi

if docker compose logs --since=5m gerrit 2>&1 | grep -E 'Failed to load plugin.*code-owners|code-owners.*(ERROR|Exception)' >/dev/null; then
  docker compose logs --since=5m gerrit >&2
  echo 'Gerrit reported a Code Owners plugin load failure.' >&2
  exit 1
fi

echo "Code Owners installed with global enforcement disabled: $PLUGIN_SHA256"
