#!/bin/sh
# mynd installer — https://get.oxhive.dev/mynd
#
# Usage:
#   curl -fsSL https://get.oxhive.dev/mynd | sh
#   curl -fsSL https://get.oxhive.dev/mynd | VERSION=v0.3.0 sh
#
# Installs the prebuilt mynd binary from GitHub Releases
# (https://github.com/oxhive/mynd/releases) into ${INSTALL_DIR:-$HOME/.local/bin}.
set -eu

repo="oxhive/mynd"
binary="mynd"
install_dir="${INSTALL_DIR:-$HOME/.local/bin}"

say() {
    printf '%s\n' "$1"
}

err() {
    printf 'error: %s\n' "$1" >&2
    exit 1
}

detect_target() {
    os=$(uname -s)
    arch=$(uname -m)

    case "$os" in
        Linux)
            case "$arch" in
                x86_64|amd64) echo "x86_64-unknown-linux-gnu" ;;
                aarch64|arm64) echo "aarch64-unknown-linux-gnu" ;;
                *) err "unsupported Linux architecture: $arch" ;;
            esac
            ;;
        Darwin)
            case "$arch" in
                arm64)
                    echo "aarch64-apple-darwin"
                    ;;
                x86_64)
                    # No x86_64-apple-darwin build is published — the shared
                    # release workflow's target matrix doesn't include one.
                    say "No prebuilt $binary binary for Intel Macs."
                    say "Install via Homebrew instead:"
                    say ""
                    say "  brew install oxhive/tap/$binary"
                    say ""
                    exit 0
                    ;;
                *) err "unsupported macOS architecture: $arch" ;;
            esac
            ;;
        *)
            err "unsupported OS: $os"
            ;;
    esac
}

release_url() {
    asset="$1"
    if [ -n "${VERSION:-}" ]; then
        echo "https://github.com/${repo}/releases/download/${VERSION}/${asset}"
    else
        echo "https://github.com/${repo}/releases/latest/download/${asset}"
    fi
}

# checksum.txt lists the versioned asset names
# (<binary>-<version>-<os>-<arch>.tar.gz), which are byte-identical to the
# <binary>-<target>.tar.gz copies this script downloads.
checksum_platform() {
    case "$1" in
        x86_64-unknown-linux-gnu) echo "linux-amd64" ;;
        aarch64-unknown-linux-gnu) echo "linux-arm64" ;;
        aarch64-apple-darwin) echo "darwin-arm64" ;;
        *) err "no checksum platform mapping for target: $1" ;;
    esac
}

sha256_of() {
    if command -v sha256sum >/dev/null 2>&1; then
        sha256sum "$1" | cut -d ' ' -f 1
    elif command -v shasum >/dev/null 2>&1; then
        shasum -a 256 "$1" | cut -d ' ' -f 1
    else
        err "need sha256sum or shasum to verify the $binary download"
    fi
}

verify_checksum() {
    archive="$1"
    sums="$2"
    target="$3"
    platform=$(checksum_platform "$target")

    expected=$(awk -v bin="$binary" -v target="$target" -v platform="$platform" '
        {
            name = $2
            sub(/^[*]/, "", name)
            prefix = bin "-"
            suffix = "-" platform ".tar.gz"
            if (name == bin "-" target ".tar.gz" ||
                (index(name, prefix) == 1 &&
                 length(name) > length(prefix suffix) &&
                 substr(name, length(name) - length(suffix) + 1) == suffix)) {
                print $1
                exit
            }
        }
    ' "$sums")

    if [ -z "$expected" ]; then
        err "checksum.txt has no entry for $binary on $target — refusing to install unverified"
    fi

    actual=$(sha256_of "$archive")
    if [ "$actual" != "$expected" ]; then
        err "checksum mismatch for $binary ($target): expected $expected, got $actual"
    fi
}

fetch() {
    url="$1"
    dest="$2"
    if command -v curl >/dev/null 2>&1; then
        curl -fsSL "$url" -o "$dest"
    elif command -v wget >/dev/null 2>&1; then
        wget -q "$url" -O "$dest"
    else
        err "need curl or wget to download $binary"
    fi
}

main() {
    target=$(detect_target)

    say "Installing $binary ($target) from $repo..."

    url=$(release_url "${binary}-${target}.tar.gz")
    sums_url=$(release_url "checksum.txt")
    tmp_dir=$(mktemp -d)
    trap 'rm -rf "$tmp_dir"' EXIT INT TERM

    archive="$tmp_dir/${binary}.tar.gz"
    if ! fetch "$url" "$archive"; then
        err "download failed: $url (no release published yet for $repo/$target?)"
    fi

    sums="$tmp_dir/checksum.txt"
    if ! fetch "$sums_url" "$sums"; then
        err "could not download $sums_url — this release has no checksum file to verify against (pin a newer VERSION)"
    fi
    verify_checksum "$archive" "$sums" "$target"
    say "Verified sha256 checksum."

    tar -xzf "$archive" -C "$tmp_dir" "$binary"

    mkdir -p "$install_dir"
    install_path="$install_dir/$binary"
    mv "$tmp_dir/$binary" "$install_path"
    chmod +x "$install_path"

    say ""
    say "Installed $binary to $install_path"

    case ":$PATH:" in
        *":$install_dir:"*)
            ;;
        *)
            say ""
            say "$install_dir is not on your PATH. Add it, e.g.:"
            say ""
            say "  export PATH=\"$install_dir:\$PATH\""
            say ""
            ;;
    esac

    say "Run '$binary --help' to get started."
    say "To run $binary in the background on login (and at boot, via loginctl linger on Linux), run:"
    say ""
    say "  $install_path service install"
    say ""
}

main
