#!/usr/bin/env bash

# The registry names rustnet's static musl build. The release also ships a gnu build,
# which mise prefers on an unqualified Linux platform unless the tool sets `libc`.
export MISE_LOCKFILE=1
export MISE_AQUA_BAKED_REGISTRY=0

REGISTRY_DIR="$PWD/aqua-registry-local"
mkdir -p "$REGISTRY_DIR"

cat <<'EOF_REGISTRY' >"$REGISTRY_DIR/registry.yml"
packages:
  - type: github_release
    repo_owner: domcyrus
    repo_name: rustnet
    files:
      - name: rustnet
        src: "{{.AssetWithoutExt}}/rustnet"
    asset: rustnet-{{.Version}}-{{.Arch}}-{{.OS}}.{{.Format}}
    format: tar.gz
    replacements:
      amd64: x86_64
      arm64: aarch64
      darwin: apple-darwin
      linux: unknown-linux-musl
EOF_REGISTRY

export MISE_AQUA_REGISTRY_URL="file://$REGISTRY_DIR"
RELEASE_URL="https://github.com/domcyrus/rustnet/releases/download/v1.6.0"

cat <<'EOF_MISE' >mise.toml
[tools]
"aqua:domcyrus/rustnet" = "1.6.0"
EOF_MISE
touch mise.lock
mise lock --platform linux-arm64
assert_contains "cat mise.lock" "url = \"$RELEASE_URL/rustnet-v1.6.0-aarch64-unknown-linux-gnu.tar.gz\""

cat <<'EOF_MISE' >mise.toml
[tools]
"aqua:domcyrus/rustnet" = { version = "1.6.0", libc = "musl" }
EOF_MISE
rm -f mise.lock
touch mise.lock
mise lock --platform linux-arm64
assert_contains "cat mise.lock" 'libc = "musl"'
assert_contains "cat mise.lock" "url = \"$RELEASE_URL/rustnet-v1.6.0-aarch64-unknown-linux-musl.tar.gz\""
assert_not_contains "cat mise.lock" "unknown-linux-gnu"

# A platform that names its libc keeps it: a gnu build cannot run on a musl target.
cat <<'EOF_MISE' >mise.toml
[tools]
"aqua:domcyrus/rustnet" = { version = "1.6.0", libc = "glibc" }
EOF_MISE
rm -f mise.lock
touch mise.lock
mise lock --platform linux-arm64,linux-x64-musl
assert_contains "cat mise.lock" 'libc = "gnu"'
assert_contains "cat mise.lock" "url = \"$RELEASE_URL/rustnet-v1.6.0-aarch64-unknown-linux-gnu.tar.gz\""
assert_contains "cat mise.lock" "url = \"$RELEASE_URL/rustnet-v1.6.0-x86_64-unknown-linux-musl.tar.gz\""

# A musl platform nobody asked for keeps the registry's asset: it names only a gnu build here,
# so mise does not go looking for a musl one.
cat <<'EOF_REGISTRY' >"$REGISTRY_DIR/registry.yml"
packages:
  - type: github_release
    repo_owner: domcyrus
    repo_name: rustnet
    files:
      - name: rustnet
        src: "{{.AssetWithoutExt}}/rustnet"
    asset: rustnet-{{.Version}}-{{.Arch}}-{{.OS}}.{{.Format}}
    format: tar.gz
    replacements:
      amd64: x86_64
      arm64: aarch64
      darwin: apple-darwin
      linux: unknown-linux-gnu
EOF_REGISTRY
cat <<'EOF_MISE' >mise.toml
[tools]
"aqua:domcyrus/rustnet" = "1.6.0"
EOF_MISE
rm -f mise.lock
touch mise.lock
mise lock --platform linux-x64-musl
assert_contains "cat mise.lock" "url = \"$RELEASE_URL/rustnet-v1.6.0-x86_64-unknown-linux-gnu.tar.gz\""
assert_not_contains "cat mise.lock" "unknown-linux-musl"

# `libc = "musl"` in settings asks for musl on every musl platform, so the gnu-only registry
# entry is still switched to the musl build, including for a platform other than the host's.
rm -f mise.lock
touch mise.lock
MISE_LIBC=musl mise lock --platform linux-x64-musl,linux-arm64-musl
assert_contains "cat mise.lock" "url = \"$RELEASE_URL/rustnet-v1.6.0-x86_64-unknown-linux-musl.tar.gz\""
assert_contains "cat mise.lock" "url = \"$RELEASE_URL/rustnet-v1.6.0-aarch64-unknown-linux-musl.tar.gz\""
assert_not_contains "cat mise.lock" "unknown-linux-gnu"

# Install the musl build on a Linux host and run it: it is statically linked, so it does
# not need libpcap. Changing `libc` for an installed version needs `--force`.
if [[ "$(uname -s)" == "Linux" ]]; then
  cat <<'EOF_MISE' >mise.toml
[tools]
"aqua:domcyrus/rustnet" = { version = "1.6.0", libc = "musl" }
EOF_MISE
  rm -f mise.lock
  mise install --force aqua:domcyrus/rustnet@1.6.0
  assert_contains "mise which rustnet" "unknown-linux-musl/rustnet"
  assert_succeed "mise x -- rustnet --version"
fi
