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

source_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
fixture_root="$(mktemp -d)"
trap 'rm -rf "$fixture_root"' EXIT

mkdir -p \
  "$fixture_root/scripts/ci" \
  "$fixture_root/backend" \
  "$fixture_root/nexuscrm-events" \
  "$fixture_root/middle" \
  "$fixture_root/replaced-active" \
  "$fixture_root/replaced-inactive" \
  "$fixture_root/shared" \
  "$fixture_root/unused"
cp "$source_root/scripts/ci/verify-workspace-private-module-pins.sh" "$fixture_root/scripts/ci/"

write_fixture() {
  events_version="$1"
  shared_version="$2"

  cat >"$fixture_root/go.work" <<'EOF'
go 1.25.0

use	(
	./backend
	./nexuscrm-events
	./shared
)
EOF
  cat >"$fixture_root/backend/go.mod" <<'EOF'
module github.com/nexuscrm/backend

go 1.25.0
EOF
  cat >"$fixture_root/nexuscrm-events/go.mod" <<EOF
module github.com/nexuscrm/events

go 1.25.0

require	(
	github.com/nexuscrm/shared v0.0.0
	github.com/pingcap-inc/nexuscrm-contract $events_version
)

replace github.com/nexuscrm/shared => ../shared
EOF
  cat >"$fixture_root/shared/go.mod" <<EOF
module github.com/nexuscrm/shared

go 1.25.0

require github.com/pingcap-inc/nexuscrm-contract $shared_version
EOF
}

release_version="v0.2.59-exp.4695.14"
write_fixture "$release_version" "$release_version"
"$fixture_root/scripts/ci/verify-workspace-private-module-pins.sh"

write_fixture "v0.2.57" "$release_version"
if output="$($fixture_root/scripts/ci/verify-workspace-private-module-pins.sh 2>&1)"; then
  echo "stale workspace contract pin unexpectedly passed" >&2
  exit 1
fi
grep -Fq "standalone graph selects $release_version from shared/go.mod, recorded pin is v0.2.57" <<<"$output"

# A main module may intentionally declare a newer compatible minimum than a
# local dependency. Only the reverse direction makes its standalone graph stale.
write_fixture "$release_version" "v0.1.2"
"$fixture_root/scripts/ci/verify-workspace-private-module-pins.sh"

older_prerelease="v0.2.59-exp.4695.13"
write_fixture "$older_prerelease" "$release_version"
if output="$($fixture_root/scripts/ci/verify-workspace-private-module-pins.sh 2>&1)"; then
  echo "stale prerelease workspace pin unexpectedly passed" >&2
  exit 1
fi
grep -Fq "standalone graph selects $release_version from shared/go.mod, recorded pin is $older_prerelease" <<<"$output"

# Main-module replacements apply to transitive requirements too. The main
# module does not directly require shared here; middle introduces it.
write_fixture "v0.2.57" "$release_version"
cat >"$fixture_root/middle/go.mod" <<'EOF'
module github.com/nexuscrm/middle

go 1.25.0

require github.com/nexuscrm/shared v0.0.0
EOF
cat >"$fixture_root/nexuscrm-events/go.mod" <<'EOF'
module github.com/nexuscrm/events

go 1.25.0

require (
	github.com/nexuscrm/middle v0.0.0
	github.com/pingcap-inc/nexuscrm-contract v0.2.57
)

replace  (
	github.com/nexuscrm/middle => ../middle
	github.com/nexuscrm/shared => ../shared
)
EOF
if output="$($fixture_root/scripts/ci/verify-workspace-private-module-pins.sh 2>&1)"; then
  echo "stale pin behind a transitive replacement unexpectedly passed" >&2
  exit 1
fi
grep -Fq "standalone graph selects $release_version from shared/go.mod, recorded pin is v0.2.57" <<<"$output"

# A replacement that is not required is not part of the module graph and must
# not raise the selected version.
cat >"$fixture_root/unused/go.mod" <<'EOF'
module github.com/nexuscrm/unused

go 1.25.0

require github.com/pingcap-inc/nexuscrm-contract v9.0.0
EOF
write_fixture "$release_version" "v0.1.2"
cat >>"$fixture_root/nexuscrm-events/go.mod" <<'EOF'

replace github.com/nexuscrm/unused => ../unused
EOF
"$fixture_root/scripts/ci/verify-workspace-private-module-pins.sh"

# Block-form replacements and an omitted indirect pin are both valid go.mod
# shapes. The former must be traversed; the latter must be reported as stale.
write_fixture "v0.2.57" "$release_version"
cat >"$fixture_root/nexuscrm-events/go.mod" <<'EOF'
module github.com/nexuscrm/events

go 1.25.0

require (
	github.com/nexuscrm/shared v0.0.0
	github.com/pingcap-inc/nexuscrm-contract v0.2.57
)

replace	(
	github.com/nexuscrm/shared => ../shared
)
EOF
if output="$($fixture_root/scripts/ci/verify-workspace-private-module-pins.sh 2>&1)"; then
  echo "stale pin behind a block replacement unexpectedly passed" >&2
  exit 1
fi
grep -Fq "standalone graph selects $release_version from shared/go.mod, recorded pin is v0.2.57" <<<"$output"

cat >"$fixture_root/nexuscrm-events/go.mod" <<'EOF'
module github.com/nexuscrm/events

go 1.25.0

require github.com/nexuscrm/shared v0.0.0

replace github.com/nexuscrm/shared => ../shared
EOF
if output="$($fixture_root/scripts/ci/verify-workspace-private-module-pins.sh 2>&1)"; then
  echo "missing selected private-module pin unexpectedly passed" >&2
  exit 1
fi
grep -Fq "recorded pin is missing" <<<"$output"

# Workspace-local replacements identify the one live source tree for an
# in-repo module and must not be version-qualified. Treating the following two
# directives as path-only would inspect the inactive v1.0.0 tree and report a
# false stale-pin failure even though Go selects v1.1.0.
write_fixture "$release_version" "v0.1.2"
cat >"$fixture_root/replaced-active/go.mod" <<EOF
module github.com/nexuscrm/replaced

go 1.25.0

require github.com/pingcap-inc/nexuscrm-contract $release_version
EOF
cat >"$fixture_root/replaced-inactive/go.mod" <<'EOF'
module github.com/nexuscrm/replaced

go 1.25.0

require github.com/pingcap-inc/nexuscrm-contract v9.0.0
EOF
cat >"$fixture_root/nexuscrm-events/go.mod" <<EOF
module github.com/nexuscrm/events

go 1.25.0

require (
	github.com/nexuscrm/replaced v1.1.0
	github.com/pingcap-inc/nexuscrm-contract $release_version
)

replace github.com/nexuscrm/replaced v1.0.0 => ../replaced-inactive

replace (
	github.com/nexuscrm/replaced v1.1.0 => ../replaced-active
)
EOF
if output="$($fixture_root/scripts/ci/verify-workspace-private-module-pins.sh 2>&1)"; then
  echo "version-specific workspace-local replacement unexpectedly passed" >&2
  exit 1
fi
grep -Fq "version-specific local replacement github.com/nexuscrm/replaced v1.0.0 => ../replaced-inactive is unsupported; workspace-local replacements must be versionless" <<<"$output"
grep -Fq "version-specific local replacement github.com/nexuscrm/replaced v1.1.0 => ../replaced-active is unsupported; workspace-local replacements must be versionless" <<<"$output"
if grep -Fq "standalone graph selects" <<<"$output"; then
  echo "version-specific replacement produced a false stale-pin diagnostic" >&2
  exit 1
fi

write_fixture "$release_version" "$release_version"
rm "$fixture_root/shared/go.mod"
if output="$($fixture_root/scripts/ci/verify-workspace-private-module-pins.sh 2>&1)"; then
  echo "missing workspace go.mod unexpectedly passed" >&2
  exit 1
fi
grep -Fq "shared/go.mod is missing" <<<"$output"

echo "workspace private module pin verifier tests: PASS"
