#!/bin/sh
set -eu

fail() {
    printf '%s\n' "gray install: $*" >&2
    exit 1
}

requested_version="${GRAY_VERSION:-}"
requested_prefix="${GRAY_HOME:-}"
modify_path=1
quiet=0
while [ "$#" -gt 0 ]; do
    case "$1" in
        --version)
            [ "$#" -ge 2 ] || fail "missing value after --version"
            requested_version=$2
            shift 2
            ;;
        --prefix)
            [ "$#" -ge 2 ] || fail "missing value after --prefix"
            requested_prefix=$2
            shift 2
            ;;
        --no-modify-path)
            modify_path=0
            shift
            ;;
        --quiet|-q)
            quiet=1
            shift
            ;;
        --help|-h)
            printf '%s\n' "Usage: install.sh [--version VERSION] [--prefix PATH] [--no-modify-path] [--quiet]"
            exit 0
            ;;
        *) fail "unknown option '$1'" ;;
    esac
done

supports_color() {
    case "${GRAY_COLOR:-auto}" in
        always) return 0 ;;
        never) return 1 ;;
        auto) ;;
        *) fail "GRAY_COLOR must be auto, always, or never" ;;
    esac
    [ -t 1 ] || return 1
    [ -z "${NO_COLOR:-}" ] || return 1
    case "${TERM:-}" in
        ''|dumb) return 1 ;;
        *) return 0 ;;
    esac
}

show_plain_banner() {
    printf '%s\n' \
        '' \
        '   _____ _____            __     __' \
        '  / ____|  __ \     /\    \ \   / /' \
        ' | |  __| |__) |   /  \    \ \_/ / ' \
        ' | | |_ |  _  /   / /\ \    \   /  ' \
        ' | |__| | | \ \  / ____ \    | |   ' \
        '  \_____|_|  \_\/_/    \_\   |_|   ' \
        '' \
        'Installing Gray' \
        ''
}

show_color_banner() {
    printf '%b\n' \
        '' \
        '\033[0;90;40m░▒▓▀▀\033[0;97;47m░░░\033[0;90;47m░░▒\033[0;37;40m \033[0;90;40m░▒▓▀▀\033[0;97;47m░\033[0;37;40m██\033[0;90;47m░░▒\033[0;37;40m \033[0;90;40m░▒▓▀▀\033[0;97;47m░\033[0;37;40m██\033[0;90;47m░░▒\033[0;37;40m \033[0;90;40m░▒▓▀▀\033[0;37;40m \033[0;90;47m▀▀▓▒░\033[0m' \
        '\033[0;90;40m▒▀\033[0;37;40m▄\033[0;97;47m░▒\033[0;97;40m \033[0;97;47m░░\033[0;90;47m  ░\033[0;37;40m \033[0;90;40m▒▀\033[0;37;40m▄\033[0;97;47m░▒\033[0;97;40m \033[0;97;47m░░\033[0;90;47m  ░\033[0;37;40m \033[0;90;40m▒▀\033[0;37;40m▄\033[0;97;47m░▒\033[0;97;40m \033[0;97;47m░░\033[0;90;47m  ░\033[0;37;40m  \033[0;97;47m▒▀▄░\033[0;37;40m \033[0;97;47m░▄▀▒\033[0;37;40m \033[0m' \
        '\033[0;37;40m▄\033[0;97;47m░░▒▓\033[0;97;40m \033[0;37;40m▀▀▀▀▀ ▄\033[0;97;47m░░▒▓\033[0;97;40m \033[0;97;47m▒▒░░ \033[0;37;40m ▄\033[0;97;47m░░▒▓\033[0;97;40m \033[0;97;47m▒▒░░ \033[0;37;40m   \033[0;97;47m▄░▒\033[0;37;40m \033[0;97;47m▒░▄\033[0;37;40m  \033[0m' \
        '\033[0;97;47m▒░▓▓▒\033[0;97;40m ▄▄▄▄▄\033[0;37;40m \033[0;97;47m▒░▓▓▒\033[0;97;40m \033[0;97;47m▓▓▓▓▒\033[0;37;40m \033[0;97;47m▒░▓▓▒\033[0;97;40m \033[0;97;47m▓▓▓▓▒\033[0;37;40m    \033[0;97;47m▒▓▓▓▒\033[0;37;40m   \033[0m' \
        '\033[0;97;47m▒▓▓██\033[0;97;40m \033[0;97;47m▒▓\033[0;97;40m███\033[0;37;40m \033[0;97;47m▒▓▓██\033[0;97;40m█\033[0;97;47m██▓▓▒\033[0;37;40m \033[0;97;47m▒▓▓██\033[0;97;40m█\033[0;97;47m██▓▓▒\033[0;37;40m    \033[0;97;47m█████\033[0;37;40m   \033[0m' \
        '\033[0;97;47m▓████\033[0;97;40m \033[0;97;47m░▒\033[0;97;40m▀\033[0;97;47m██\033[0;37;40m \033[0;97;47m▓████\033[0;97;40m▀\033[0;97;47m▓███\033[0;37;40m  \033[0;97;47m▓████\033[0;97;40m \033[0;97;47m▓████\033[0;37;40m    \033[0;97;47m█████\033[0;37;40m   \033[0m' \
        '\033[0;97;47m█████\033[0;97;40m▄▄▄▄\033[0;97;47m██\033[0;37;40m \033[0;97;47m█████\033[0;97;40m \033[0;97;47m█████\033[0;37;40m \033[0;97;47m█████\033[0;97;40m \033[0;97;47m█████\033[0;37;40m    \033[0;97;47m█████\033[0;37;40m   \033[0m' \
        '' \
        'Installing Gray' \
        ''
}

show_banner() {
    [ "$quiet" -eq 0 ] || return 0
    if supports_color; then
        show_color_banner
    else
        show_plain_banner
    fi
}

progress() {
    [ "$quiet" -eq 0 ] || return 0
    case "$1" in
        1) progress_fill='━━━━'; progress_track='────────────────'; progress_percent=20 ;;
        2) progress_fill='━━━━━━━━'; progress_track='────────────'; progress_percent=40 ;;
        3) progress_fill='━━━━━━━━━━━━'; progress_track='────────'; progress_percent=60 ;;
        4) progress_fill='━━━━━━━━━━━━━━━━'; progress_track='────'; progress_percent=80 ;;
        5) progress_fill='━━━━━━━━━━━━━━━━━━━━'; progress_track=''; progress_percent=100 ;;
        *) fail "invalid installer progress step '$1'" ;;
    esac
    if supports_color; then
        printf '  \033[0;97m%s\033[0;90m%s\033[0m  %s%%  %s\n' \
            "$progress_fill" "$progress_track" "$progress_percent" "$2"
    else
        printf '  %s%%  %s\n' "$progress_percent" "$2"
    fi
}

detail() {
    [ "$quiet" -eq 0 ] || return 0
    printf '  %s: %s\n' "$1" "$2"
}

show_banner
progress 1 'Detecting platform'
machine="$(uname -s)-$(uname -m)"
case "$machine" in
    Darwin-arm64|Darwin-aarch64) platform=macos-aarch64 ;;
    Darwin-x86_64)
        if command -v sysctl >/dev/null 2>&1 &&
            [ "$(sysctl -n hw.optional.arm64 2>/dev/null || true)" = 1 ]; then
            platform=macos-aarch64
        else
            fail "unsupported platform '$machine'; expected macOS arm64 or Linux x86-64"
        fi
        ;;
    Linux-x86_64|Linux-amd64) platform=linux-x86_64 ;;
    *) fail "unsupported platform '$machine'; expected macOS arm64 or Linux x86-64" ;;
esac
detail platform "$platform"

registry="${GRAY_RELEASE_REGISTRY:-https://archive.graylanguage.com}"
case "$registry" in
    https://*) ;;
    *) fail "GRAY_RELEASE_REGISTRY must use HTTPS" ;;
esac
version="$requested_version"
if [ -z "$version" ]; then
    command -v curl >/dev/null 2>&1 || fail "curl is required"
    version="$(curl --fail --silent --show-error --location \
        --proto '=https' --tlsv1.2 "$registry/v1/releases/latest/$platform")"
fi
printf '%s\n' "$version" | grep -Eq \
    '^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$' || \
    fail "GRAY_VERSION must be an exact SemVer version"

gray_home="${requested_prefix:-${HOME:?HOME is required}/.gray}"
case "$gray_home" in
    /*) ;;
    *) fail "GRAY_HOME must be an absolute path" ;;
esac

for command in tar awk grep sed mktemp find mkdir mv chmod install ln readlink; do
    command -v "$command" >/dev/null 2>&1 || \
        fail "required command '$command' is unavailable"
done

temporary="$(mktemp -d "${TMPDIR:-/tmp}/gray-install.XXXXXX")"
trap 'rm -rf -- "$temporary"' EXIT HUP INT TERM
sha256_file() {
    if command -v sha256sum >/dev/null 2>&1; then
        sha256sum "$1" | awk '{print $1}'
    elif command -v shasum >/dev/null 2>&1; then
        shasum -a 256 "$1" | awk '{print $1}'
    else
        fail "sha256sum or shasum is required"
    fi
}

require_digest() {
    label=$1
    path=$2
    expected_digest=$3
    printf '%s\n' "$expected_digest" | grep -Eq '^[0-9a-f]{64}$' ||
        fail "$label checksum is not a lowercase SHA-256 digest"
    observed_digest="$(sha256_file "$path")"
    [ "$observed_digest" = "$expected_digest" ] ||
        fail "$label SHA-256 mismatch"
}

json_key_count() {
    awk -v token="\"$1\"" '
        {
            text = $0
            while ((position = index(text, token)) > 0) {
                count++
                text = substr(text, position + length(token))
            }
        }
        END { print count + 0 }
    '
}

manager_registry="${GRAY_MANAGER_REGISTRY:-https://get.graylanguage.com}"
case "$manager_registry" in
    https://*) ;;
    *) fail "GRAY_MANAGER_REGISTRY must use HTTPS" ;;
esac
manager_version="${GRAY_MANAGER_VERSION:-}"
if [ -z "$manager_version" ]; then
    command -v curl >/dev/null 2>&1 || fail "curl is required"
    manager_version="$(curl --fail --silent --show-error --location \
        --proto '=https' --tlsv1.2 \
        "$manager_registry/v1/managers/latest/$platform")"
fi
printf '%s\n' "$manager_version" | grep -Eq \
    '^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$' ||
    fail "GRAY_MANAGER_VERSION must be an exact SemVer version"

progress 2 'Verifying Gray manager'
manager_download="$temporary/gray-manager"
if [ -n "${GRAY_MANAGER_BINARY:-}" ]; then
    [ -f "$GRAY_MANAGER_BINARY" ] && [ ! -L "$GRAY_MANAGER_BINARY" ] ||
        fail "GRAY_MANAGER_BINARY is not a regular file"
    manager_source="$(cd "$(dirname "$GRAY_MANAGER_BINARY")" && pwd -P)/$(basename "$GRAY_MANAGER_BINARY")"
    cp "$manager_source" "$manager_download"
else
    command -v curl >/dev/null 2>&1 || fail "curl is required"
    curl --fail --silent --show-error --location \
        --proto '=https' --tlsv1.2 --output "$manager_download" \
        "$manager_registry/v1/managers/$manager_version/$platform/gray-manager"
fi
manager_expected="${GRAY_MANAGER_SHA256:-}"
if [ -z "$manager_expected" ]; then
    manager_expected="$(curl --fail --silent --show-error --location \
        --proto '=https' --tlsv1.2 \
        "$manager_registry/v1/managers/$manager_version/$platform/gray-manager.sha256" |
        awk 'NR == 1 {print $1}')"
fi
require_digest "manager" "$manager_download" "$manager_expected"
chmod 0755 "$manager_download"
detail manager "$manager_version"
detail 'manager checksum' verified

launcher_download="$temporary/gray-launcher"
if [ -n "${GRAY_LAUNCHER_SOURCE:-}" ]; then
    [ -f "$GRAY_LAUNCHER_SOURCE" ] && [ ! -L "$GRAY_LAUNCHER_SOURCE" ] ||
        fail "GRAY_LAUNCHER_SOURCE is not a regular file"
    launcher_source="$(cd "$(dirname "$GRAY_LAUNCHER_SOURCE")" && pwd -P)/$(basename "$GRAY_LAUNCHER_SOURCE")"
    cp "$launcher_source" "$launcher_download"
else
    command -v curl >/dev/null 2>&1 || fail "curl is required"
    curl --fail --silent --show-error --location \
        --proto '=https' --tlsv1.2 --output "$launcher_download" \
        "$manager_registry/launcher.sh"
fi
launcher_expected="${GRAY_LAUNCHER_SHA256:-}"
if [ -z "$launcher_expected" ]; then
    launcher_expected="$(curl --fail --silent --show-error --location \
        --proto '=https' --tlsv1.2 "$manager_registry/launcher.sh.sha256" |
        awk 'NR == 1 {print $1}')"
fi
require_digest "launcher" "$launcher_download" "$launcher_expected"
detail 'launcher checksum' verified

progress 3 'Verifying Gray toolchain'
detail toolchain "$version"
mkdir -p "$gray_home/bin" \
    "$gray_home/managers/$manager_version/$platform/bin" \
    "$gray_home/versions/$version"
target="$gray_home/versions/$version/$platform"
if [ ! -e "$target" ] && [ ! -L "$target" ]; then
    archive="$temporary/gray.tar.gz"
    if [ -n "${GRAY_INSTALL_ARCHIVE:-}" ]; then
        [ -f "$GRAY_INSTALL_ARCHIVE" ] && [ ! -L "$GRAY_INSTALL_ARCHIVE" ] ||
            fail "GRAY_INSTALL_ARCHIVE is not a regular file"
        archive_source="$(cd "$(dirname "$GRAY_INSTALL_ARCHIVE")" && pwd -P)/$(basename "$GRAY_INSTALL_ARCHIVE")"
        cp "$archive_source" "$archive"
    else
        command -v curl >/dev/null 2>&1 || fail "curl is required"
        curl --fail --silent --show-error --location \
            --proto '=https' --tlsv1.2 --output "$archive" \
            "$registry/v1/releases/$version/$platform"
    fi
    expected="${GRAY_INSTALL_SHA256:-}"
    if [ -z "$expected" ]; then
        expected="$(curl --fail --silent --show-error --location \
            --proto '=https' --tlsv1.2 \
            "$registry/v1/releases/$version/$platform.sha256" |
            awk 'NR == 1 {print $1}')"
    fi
    require_digest "archive" "$archive" "$expected"
    detail 'toolchain checksum' verified
    listing="$temporary/listing"
    tar -tzf "$archive" >"$listing" || fail "cannot read release archive"
    top="$(awk -F/ '
        BEGIN { top = "" }
        /^\// { exit 2 }
        {
            if ($1 == "" || $1 == "." || $1 == "..") exit 2
            for (i = 1; i <= NF; i++) if ($i == "..") exit 2
            if (top == "") top = $1
            if ($1 != top) exit 3
        }
        END { if (top == "") exit 4; print top }
    ' "$listing")" || fail "archive paths are unsafe or have multiple roots"
    expected_root="gray-$version-$platform"
    [ "$top" = "$expected_root" ] ||
        fail "archive root '$top' does not match release identity '$expected_root'"
    extracted="$temporary/extracted"
    mkdir -p "$extracted"
    tar -xzf "$archive" -C "$extracted" || fail "cannot extract release archive"
    bundle="$extracted/$top"
    [ -d "$bundle" ] && [ ! -L "$bundle" ] || fail "invalid bundle root"
    if find "$bundle" -type l -o ! -type d ! -type f | grep -q .; then
        fail "bundle contains links or unsupported file types"
    fi
    [ -x "$bundle/bin/gray" ] || fail "bundle has no Gray executable"
    release_metadata="$bundle/share/gray/release.json"
    [ -f "$release_metadata" ] && [ ! -L "$release_metadata" ] ||
        fail "bundle has no trusted release metadata"
    LC_ALL=C grep -Eq '^\{"artifact_version":"[A-Za-z0-9._-]+","binary":\{"bytes":[0-9]+,"path":"bin/gray","sha256":"[0-9a-f]{64}"\},"channel":"(development|prerelease)","gray_version":"[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?","license_gate":"blocked","official":false,"platform":"(macos-aarch64|linux-x86_64)","schema":"gray.runtime-bundle.v1","source_date_epoch":[0-9]+,"source_revision":("[0-9a-f]{40}"|null)\}$' \
        "$release_metadata" || fail "bundle release metadata is not canonical"
    metadata_schema="$(sed -n 's/.*"schema"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$release_metadata")"
    metadata_version="$(sed -n 's/.*"gray_version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$release_metadata")"
    metadata_platform="$(sed -n 's/.*"platform"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$release_metadata")"
    metadata_artifact="$(sed -n 's/.*"artifact_version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$release_metadata")"
    metadata_binary_path="$(sed -n 's/.*"path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$release_metadata")"
    metadata_binary_digest="$(sed -n 's/.*"sha256"[[:space:]]*:[[:space:]]*"\([0-9a-f]*\)".*/\1/p' "$release_metadata")"
    metadata_binary_bytes="$(sed -n 's/.*"bytes"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p' "$release_metadata")"
    [ "$metadata_schema" = gray.runtime-bundle.v1 ] ||
        fail "bundle release metadata has an invalid schema"
    [ "$metadata_version" = "$version" ] ||
        fail "bundle metadata version '$metadata_version' does not match requested version '$version'"
    [ "$metadata_platform" = "$platform" ] ||
        fail "bundle metadata platform '$metadata_platform' does not match requested platform '$platform'"
    [ -n "$metadata_artifact" ] || fail "bundle metadata has no artifact version"
    [ "$metadata_binary_path" = bin/gray ] ||
        fail "bundle metadata has an invalid binary path"
    require_digest "bundle Gray executable" "$bundle/bin/gray" "$metadata_binary_digest"
    observed_binary_bytes="$(wc -c <"$bundle/bin/gray" | tr -d '[:space:]')"
    [ "$observed_binary_bytes" = "$metadata_binary_bytes" ] ||
        fail "bundle Gray executable size does not match release metadata"
    binary_identity="$("$bundle/bin/gray" version --json)" ||
        fail "bundle Gray executable did not report its identity"
    case "$binary_identity" in
        \{*\}) ;;
        *) fail "bundle Gray executable reported an invalid identity object" ;;
    esac
    binary_identity_body="${binary_identity#\{}"
    binary_identity_body="${binary_identity_body%\}}"
    if printf '%s\n' "$binary_identity_body" | grep -Eq '[{}\[\]]'; then
        fail "bundle Gray executable reported a nested identity object"
    fi
    for identity_key in schema gray_version platform artifact_version; do
        [ "$(printf '%s\n' "$binary_identity_body" | json_key_count "$identity_key")" = 1 ] ||
            fail "bundle Gray executable reported a duplicate or missing identity field"
    done
    binary_schema="$(printf '%s\n' "$binary_identity" | sed -n 's/.*"schema"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')"
    binary_version="$(printf '%s\n' "$binary_identity" | sed -n 's/.*"gray_version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')"
    binary_platform="$(printf '%s\n' "$binary_identity" | sed -n 's/.*"platform"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')"
    binary_artifact="$(printf '%s\n' "$binary_identity" | sed -n 's/.*"artifact_version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')"
    [ "$binary_schema" = gray.version.v1 ] ||
        fail "bundle Gray executable reported an invalid identity schema"
    [ "$binary_version" = "$version" ] ||
        fail "binary version '$binary_version' does not match requested version '$version'"
    [ "$binary_platform" = "$platform" ] ||
        fail "binary platform '$binary_platform' does not match requested platform '$platform'"
    [ "$binary_artifact" = "$metadata_artifact" ] ||
        fail "binary artifact '$binary_artifact' does not match release metadata '$metadata_artifact'"
    mv "$bundle" "$target"
elif [ -L "$target" ] || [ ! -x "$target/bin/gray" ]; then
    fail "existing Gray $version installation is unsafe or incomplete"
else
    detail 'toolchain checksum' 'previously verified installation'
fi

progress 4 'Activating Gray'
detail destination "$gray_home"
# Do not activate the manager or launcher until the requested toolchain has
# passed every archive and checksum check. A failed first install must not
# leave a runnable partial installation behind.
manager_target="$gray_home/managers/$manager_version/$platform/bin/gray-manager"
manager_tmp="$manager_target.tmp.$$"
install -m 0755 "$manager_download" "$manager_tmp"
mv "$manager_tmp" "$manager_target"

manager_config_tmp="$gray_home/.manager.tmp.$$"
printf '{"manager_version":"%s"}\n' "$manager_version" \
    >"$manager_config_tmp"
chmod 0600 "$manager_config_tmp"
mv "$manager_config_tmp" "$gray_home/manager.json"

launcher_tmp="$gray_home/bin/.gray.tmp.$$"
awk -v platform="$platform" \
    '{gsub(/@PLATFORM@/, platform); print}' \
    "$launcher_download" >"$launcher_tmp"
chmod 0755 "$launcher_tmp"
mv "$launcher_tmp" "$gray_home/bin/gray"

if [ ! -f "$gray_home/config.json" ]; then
    config_tmp="$gray_home/.config.tmp.$$"
    printf '{"default_version":"%s"}\n' "$version" >"$config_tmp"
    chmod 0600 "$config_tmp"
    mv "$config_tmp" "$gray_home/config.json"
fi

if [ "$quiet" -eq 1 ]; then
    GRAY_HOME="$gray_home" "$gray_home/bin/gray" doctor --first-install \
        >/dev/null || fail "installed Gray failed first-install diagnostics"
else
    GRAY_HOME="$gray_home" "$gray_home/bin/gray" doctor --first-install ||
        fail "installed Gray failed first-install diagnostics"
fi

if [ "$quiet" -eq 0 ]; then
    printf '%s\n' "Installed Gray manager $manager_version and Gray $version for $platform in $gray_home"
fi
immediate_path_dir=''
if [ "$modify_path" -eq 1 ]; then
    : "${HOME:?HOME is required to configure PATH}"
    shell_name=${SHELL##*/}
    case "$shell_name" in
        zsh)
            profile_root=${ZDOTDIR:-$HOME}
            case "$profile_root" in
                /*) ;;
                *) profile_root="$HOME/$profile_root" ;;
            esac
            profile="$profile_root/.zshrc"
            ;;
        bash)
            case "$platform" in
                macos-*) profile="$HOME/.bash_profile" ;;
                *) profile="$HOME/.bashrc" ;;
            esac
            ;;
        fish)
            profile_root=${XDG_CONFIG_HOME:-$HOME/.config}
            case "$profile_root" in
                /*) ;;
                *) profile_root="$HOME/$profile_root" ;;
            esac
            profile="$profile_root/fish/config.fish"
            ;;
        *) profile="$HOME/.profile" ;;
    esac
    mkdir -p "$(dirname "$profile")"
    if [ "$shell_name" = fish ]; then
        quoted_home="$(printf '%s' "$gray_home" | sed "s/'/\\\\'/g")"
        path_line="set -gx GRAY_HOME '$quoted_home'; fish_add_path --prepend \"\$GRAY_HOME/bin\" # Gray"
    else
        quoted_home="$(printf '%s' "$gray_home" | sed "s/'/'\\\\''/g")"
        path_line="export GRAY_HOME='$quoted_home'; export PATH=\"\$GRAY_HOME/bin:\$PATH\" # Gray"
    fi
    if [ ! -f "$profile" ] || ! grep -Fqx "$path_line" "$profile"; then
        printf '\n%s\n' "$path_line" >>"$profile"
    fi
    if [ "$quiet" -eq 0 ]; then
        printf '%s\n' "Configured $gray_home/bin in $profile."
    fi

    # A piped installer cannot alter its parent shell's environment. Make the
    # command available to that shell anyway by linking it into a writable,
    # user-owned directory that is already present in the current PATH.
    original_ifs=$IFS
    IFS=:
    for candidate_dir in ${PATH:-}; do
        IFS=$original_ifs
        case "$candidate_dir" in
            "$HOME"|"$HOME"/*) ;;
            *) IFS=:; continue ;;
        esac
        [ "$candidate_dir" != "$gray_home/bin" ] || {
            IFS=:
            continue
        }
        if [ ! -d "$candidate_dir" ]; then
            case "$candidate_dir" in
                "$HOME/bin"|"$HOME/.local/bin") mkdir -p "$candidate_dir" ;;
                *) IFS=:; continue ;;
            esac
        fi
        [ -w "$candidate_dir" ] || {
            IFS=:
            continue
        }
        candidate_link="$candidate_dir/gray"
        if [ -L "$candidate_link" ] &&
            [ "$(readlink "$candidate_link")" = "$gray_home/bin/gray" ]; then
            immediate_path_dir=$candidate_dir
            break
        fi
        if [ ! -e "$candidate_link" ] && [ ! -L "$candidate_link" ]; then
            ln -s "$gray_home/bin/gray" "$candidate_link"
            immediate_path_dir=$candidate_dir
            break
        fi
        IFS=:
    done
    IFS=$original_ifs
fi
detail diagnostics passed
if [ -n "$immediate_path_dir" ]; then
    detail command "gray (available now via $immediate_path_dir)"
else
    detail command "$gray_home/bin/gray"
fi
progress 5 'Gray is ready'
