#!/usr/bin/env bash

set -Eeuo pipefail

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

if ! command -v go >/dev/null 2>&1; then
  echo "error: Go is not installed or is not available in PATH" >&2
  exit 1
fi

cd "${WORKSPACE_ROOT}"

if [[ ! -f go.work ]]; then
  echo "error: go.work was not found in ${WORKSPACE_ROOT}" >&2
  exit 1
fi

mapfile -t modules < <(go list -m -f '{{.Dir}}')
if (( ${#modules[@]} == 0 )); then
  echo "error: no workspace modules were found" >&2
  exit 1
fi

echo "Updating dependencies for ${#modules[@]} workspace modules..."

for module_dir in "${modules[@]}"; do
  module_name="$(cd -- "${module_dir}" && go list -m -f '{{.Path}}')"
  echo
  echo "==> ${module_name} (${module_dir})"

  (
    cd -- "${module_dir}"
    if ! go get -u ./...; then
      echo "warning: dependency update failed; retrying with the current genproto parent module" >&2
      # Older transitive gRPC dependencies can select the pre-split genproto
      # module alongside the current googleapis/api and googleapis/rpc modules.
      # Seeding the current parent version lets MVS resolve a non-overlapping set;
      # go mod tidy removes this requirement afterward when it is not needed.
      go get google.golang.org/genproto@latest
      go get -u ./...
    fi
    go mod tidy
  )
done

echo
echo "==> Pinning the current genproto parent module for workspace compatibility"
(
  cd -- "${modules[0]}"
  go get google.golang.org/genproto@latest
)

echo
echo "==> Synchronizing go.work"
go work sync

echo
echo "Dependency update completed successfully. Review and test the changes before committing."
