#!/bin/sh
# script/install-goreleaser: install the pinned goreleaser into the
# repo-local tool directory. Our own extension to
# scripts-to-rule-them-all. Idempotent: exits immediately when the
# pinned version is already available.
#
# script/bootstrap calls this, and so does .gitea/workflows/release.yml.
# It is a separate script rather than an inline block in bootstrap
# because bootstrap deliberately hard-fails on a machine without a
# usable Docker daemon (Docker gates script/lint, and therefore
# script/check), while the release runner needs goreleaser and does not
# need Docker. One script, two callers, no duplicated pin.
#
# The install is a specific GitHub release archive verified against the
# sha256 hardcoded below, per REPO_POLICIES.md: no `curl | sh`, no
# `@latest`, no version tag that a server can move. Bumping goreleaser
# means editing GORELEASER_VERSION *and* the four checksums, which are
# taken from the checksums.txt published with that release.
set -eu

ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"

# goreleaser v2.17.1, 2026-08-05. Checksums are from
# https://github.com/goreleaser/goreleaser/releases/download/v2.17.1/checksums.txt
GORELEASER_VERSION="2.17.1"
SHA256_LINUX_X86_64="a99bbc7ae0d8d897b07c4c497a9b62f222558804715ef219d1af05a7e417bc80"
SHA256_LINUX_ARM64="702f03769ac8bcb0e47839c82243cc614ae995633599a98c63062e13ea85f829"
SHA256_DARWIN_X86_64="a92a68c61a6833ff67748f532cbebc7b8e49ba30de062ab463b221211ee6368f"
SHA256_DARWIN_ARM64="b65624885c25da9a677b7ad11cf86a02123cc5a56af66f6b4ebb574658eada2e"

TOOLBIN="$ROOT/.tool/bin"

# Print the version of the goreleaser at $1, or nothing if it is not
# usable. `goreleaser --version` prints a multi-line banner; the version
# is on the line beginning "GitVersion:".
goreleaser_version() {
    [ -x "$1" ] || return 0
    "$1" --version 2>/dev/null |
        sed -n 's/^ *GitVersion: *//p' |
        head -n 1
}

verify_sha256() {
    file="$1"
    want="$2"
    if command -v sha256sum >/dev/null 2>&1; then
        got="$(sha256sum "$file" | cut -d' ' -f1)"
    elif command -v shasum >/dev/null 2>&1; then
        got="$(shasum -a 256 "$file" | cut -d' ' -f1)"
    else
        echo "install-goreleaser: no sha256sum or shasum available" >&2
        return 1
    fi
    if [ "$got" != "$want" ]; then
        echo "install-goreleaser: checksum mismatch for $file" >&2
        echo "  expected: $want" >&2
        echo "  actual:   $got" >&2
        return 1
    fi
}

main() {
    cd "$ROOT"

    # Already have it, either on PATH or from a previous run? Then stop.
    # An arbitrary PATH goreleaser is NOT accepted: the config uses
    # version-2 schema features, and the whole point of pinning is that
    # a release is cut by a known build of a known tool.
    if [ "$(goreleaser_version "$(command -v goreleaser || true)")" \
        = "$GORELEASER_VERSION" ]; then
        echo "goreleaser $GORELEASER_VERSION already on PATH"
        return 0
    fi
    if [ "$(goreleaser_version "$TOOLBIN/goreleaser")" \
        = "$GORELEASER_VERSION" ]; then
        echo "goreleaser $GORELEASER_VERSION already installed in .tool/bin"
        return 0
    fi

    os="$(uname -s)"
    arch="$(uname -m)"
    case "$os" in
        Linux) ;;
        Darwin) ;;
        *)
            echo "install-goreleaser: unsupported OS $os" >&2
            exit 1
            ;;
    esac
    case "$arch" in
        x86_64 | amd64) arch="x86_64" ;;
        arm64 | aarch64) arch="arm64" ;;
        *)
            echo "install-goreleaser: unsupported architecture $arch" >&2
            exit 1
            ;;
    esac

    case "${os}_${arch}" in
        Linux_x86_64) sum="$SHA256_LINUX_X86_64" ;;
        Linux_arm64) sum="$SHA256_LINUX_ARM64" ;;
        Darwin_x86_64) sum="$SHA256_DARWIN_X86_64" ;;
        Darwin_arm64) sum="$SHA256_DARWIN_ARM64" ;;
        *)
            echo "install-goreleaser: no pinned checksum for ${os}_${arch}" >&2
            exit 1
            ;;
    esac

    archive="goreleaser_${os}_${arch}.tar.gz"
    url="https://github.com/goreleaser/goreleaser/releases/download/v${GORELEASER_VERSION}/${archive}"

    if ! command -v curl >/dev/null 2>&1; then
        echo "install-goreleaser: curl is required" >&2
        exit 1
    fi

    tmp="$(mktemp -d)"
    # shellcheck disable=SC2064 # expand $tmp now, not at trap time
    trap "rm -rf '$tmp'" EXIT INT TERM

    echo "installing goreleaser $GORELEASER_VERSION for ${os}_${arch}"
    curl -fsSL --retry 3 -o "$tmp/$archive" "$url"
    verify_sha256 "$tmp/$archive" "$sum"

    tar -xzf "$tmp/$archive" -C "$tmp" goreleaser
    mkdir -p "$TOOLBIN"
    # Move into place via a temp name in the destination directory so a
    # concurrent run never observes a half-written binary.
    mv "$tmp/goreleaser" "$TOOLBIN/.goreleaser.$$"
    chmod 0755 "$TOOLBIN/.goreleaser.$$"
    mv "$TOOLBIN/.goreleaser.$$" "$TOOLBIN/goreleaser"

    installed="$(goreleaser_version "$TOOLBIN/goreleaser")"
    if [ "$installed" != "$GORELEASER_VERSION" ]; then
        echo "install-goreleaser: installed binary reports '$installed'," \
            "expected '$GORELEASER_VERSION'" >&2
        exit 1
    fi

    echo "goreleaser $GORELEASER_VERSION installed to .tool/bin"
}

main "$@"
