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

log() {
  printf '[go-mod-tidy-all] %s\n' "$*"
}

fail() {
  printf '[go-mod-tidy-all] ERROR: %s\n' "$*" >&2
  exit 1
}

require_cmd() {
  command -v "$1" >/dev/null 2>&1 || fail "missing required command: $1"
}

usage() {
  cat <<'EOF'
Run go mod tidy in every Go module under this repository.

Usage:
  bash scripts/go-mod-tidy-all.sh [go mod tidy args...]

Examples:
  bash scripts/go-mod-tidy-all.sh
  bash scripts/go-mod-tidy-all.sh -v
EOF
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
  usage
  exit 0
fi

require_cmd go
require_cmd find
require_cmd sort

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"

mapfile -t GO_MOD_FILES < <(
  find "${REPO_ROOT}" \
    \( \
      -path "${REPO_ROOT}/.git" \
      -o -path "${REPO_ROOT}/output" \
      -o -path "${REPO_ROOT}/.tmp" \
      -o -path "${REPO_ROOT}/.mypy_cache" \
    \) -prune \
    -o -type f -name go.mod -print | sort
)

if [[ "${#GO_MOD_FILES[@]}" -eq 0 ]]; then
  fail "no go.mod files found under ${REPO_ROOT}"
fi

for go_mod_file in "${GO_MOD_FILES[@]}"; do
  module_dir="$(dirname -- "${go_mod_file}")"
  module_name="${module_dir#${REPO_ROOT}/}"
  if [[ "${module_name}" == "${module_dir}" ]]; then
    module_name="."
  fi

  log "tidying ${module_name}"
  (
    cd "${module_dir}"
    go mod tidy "$@"
  )
done

log "tidied ${#GO_MOD_FILES[@]} module(s)"
