#!/usr/bin/env bash
# 先安装 Dever 本体，再后台准备私有编译环境；--wait 用于同步安装。
set -euo pipefail

version=${DEVER_VERSION:-@DEVER_VERSION@}
install_root=${DEVER_INSTALL_DIR:-"$HOME/.dever"}
release_url=
modify_path=true
wait_for_environment=false
while (( $# )); do
    case "$1" in
        --version) version=${2:?--version requires a value}; shift 2 ;;
        --prefix) install_root=${2:?--prefix requires a value}; shift 2 ;;
        --release-url) release_url=${2:?--release-url requires a value}; shift 2 ;;
        --no-modify-path) modify_path=false; shift ;;
        --wait) wait_for_environment=true; shift ;;
        --help|-h)
            echo 'Usage: bash install [--version VERSION] [--prefix DIRECTORY] [--release-url URL] [--no-modify-path] [--wait]'
            exit 0 ;;
        *) echo "Unknown option: $1" >&2; exit 1 ;;
    esac
done
if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    echo 'Specify --version, or use the installer attached to a Dever release.' >&2
    exit 1
fi
if [[ $(uname -s) != Linux || $(uname -m) != x86_64 ]]; then
    echo 'This release supports Linux x86_64 only.' >&2
    exit 1
fi
for tool in curl tar xz sha256sum flock getconf nohup; do
    command -v "$tool" >/dev/null || { echo "Required installer tool: $tool" >&2; exit 1; }
done
glibc=$(getconf GNU_LIBC_VERSION)
glibc=${glibc#glibc }
if [[ $(printf '%s\n' 2.41 "$glibc" | sort -V | head -n 1) != 2.41 ]]; then
    echo 'This release requires glibc 2.41 or newer; Debian 13 is validated.' >&2
    exit 1
fi
mkdir -p "$install_root"
install_root=$(cd "$install_root" && pwd -P)
exec 9>"$install_root/.install.lock"
flock -n 9 || { echo 'Another Dever installation is running.' >&2; exit 1; }
mkdir -p "$install_root/bin" "$install_root/versions" "$install_root/toolchains" "$install_root/cache/cargo"
stage=$(mktemp -d "$install_root/.install.XXXXXX")
trap 'rm -rf -- "$stage"' EXIT
release_url=${release_url:-"https://git.dever.cc/dever/core/releases/download/v$version"}
release_url=${release_url%/}
triple=x86_64-unknown-linux-gnu

download() {
    local url=$1 file=$2
    curl --fail --location --show-error --progress-bar --retry 2 "$url" --output "$file"
}

verified_download() {
    local url=$1 file=$2
    download "$url" "$file"
    download "$url.sha256" "$file.sha256"
    (cd "$(dirname "$file")" && sha256sum --check "$(basename "$file").sha256")
}

destination="$install_root/versions/$version"
if [[ -d $destination ]]; then
    package=$destination
    echo "Reusing Dever $version."
else
    echo "Downloading Dever $version."
    archive="dever-$version-linux-x86_64.tar.xz"
    verified_download "$release_url/$archive" "$stage/$archive"
    tar -xJf "$stage/$archive" -C "$stage"
    package="$stage/dever"
fi
read -r rust_version native_id < "$package/toolchain/online"
if [[ ! $rust_version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ || ! $native_id =~ ^[a-f0-9]{64}$ ]]; then
    echo 'Invalid toolchain metadata in the downloaded release.' >&2
    exit 1
fi
if [[ $package != "$destination" ]]; then
    # 暂存包与正式版本目录深度一致，使用相对链接共享工具和依赖缓存。
    ln -s "../../../toolchains/rust-$rust_version-$triple" "$package/toolchain/rust"
    ln -s "../../../toolchains/native-$native_id/native" "$package/toolchain/native"
    ln -s "../../../toolchains/native-$native_id/lib" "$package/toolchain/lib"
    ln -s ../../../cache/cargo "$package/toolchain/cache"
fi
"$package/bin/dever" skill path >/dev/null
printf '%s\n%s\n' "$release_url" "${RUSTUP_DIST_SERVER:-https://static.rust-lang.org}" > "$package/toolchain/sources.new"
mv "$package/toolchain/sources.new" "$package/toolchain/sources"
if [[ $package != "$destination" ]]; then
    mv "$package" "$destination"
fi
# 本体验证成功即可使用源码工具；编译命令等待后台环境准备完成。
ln -s "../versions/$version/bin/dever" "$stage/command"
mv -Tf "$stage/command" "$install_root/bin/dever"
printf 'export PATH=%q/bin:$PATH\n' "$install_root" > "$install_root/env"
if $modify_path; then
    shell_name=${SHELL:-/bin/sh}
    case "${shell_name##*/}" in
        zsh) profile="$HOME/.zshrc" ;;
        bash) profile="$HOME/.bashrc" ;;
        *) profile="$HOME/.profile" ;;
    esac
    printf -v path_line '. %q' "$install_root/env"
    if [[ ! -f $profile ]] || ! grep -Fqx "$path_line" "$profile"; then
        printf '\n%s\n' "$path_line" >> "$profile"
    fi
fi
"$install_root/bin/dever" --version
printf 'Dever installed. Open a new terminal, or run: . %q\n' "$install_root/env"
echo 'Start a project: dever new hello'
flock -u 9
if $wait_for_environment; then
    bash "$destination/toolchain/prepare"
elif [[ ! -f $destination/toolchain/ready ]]; then
    nohup bash "$destination/toolchain/prepare" </dev/null >/dev/null 2>&1 9>&- &
    echo 'The build environment is preparing in the background. You can create, edit and check projects now.'
    echo 'run/test/build will wait automatically if preparation is still in progress.'
else
    echo 'Dever build environment is ready.'
fi
