#!/bin/sh
# Install a published OpenLore release. Inspect this script before running it.
set -eu

main() {
    version=latest
    install_dir=${HOME:?HOME must be set}/.local/bin
    while [ "$#" -gt 0 ]; do
        case "$1" in
            --version|--install-dir)
                [ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; exit 1; }
                case "$1" in
                    --version) version=$2 ;;
                    --install-dir) install_dir=$2 ;;
                esac
                shift 2 ;;
            --help)
                echo 'Usage: sh install.sh [--version v0.7.5] [--install-dir /path/to/bin]'
                return ;;
            *) echo "Unknown option: $1" >&2; exit 1 ;;
        esac
    done

    case "$(uname -s)" in
        Darwin) os=darwin ;;
        Linux) os=linux ;;
        *) echo 'Supported platforms: macOS and Linux. For Windows, use https://openlore.sh/guides/installation/' >&2; exit 1 ;;
    esac
    case "$(uname -m)" in
        x86_64|amd64) arch=amd64 ;;
        arm64|aarch64) arch=arm64 ;;
        *) echo 'Supported architectures: x86-64 and ARM64.' >&2; exit 1 ;;
    esac
    for tool in curl tar awk mktemp; do
        command -v "$tool" >/dev/null 2>&1 || { echo "Required command not found: $tool" >&2; exit 1; }
    done
    if command -v sha256sum >/dev/null 2>&1; then
        checksum_tool=sha256sum
    elif command -v shasum >/dev/null 2>&1; then
        checksum_tool=shasum
    else
        echo 'SHA-256 verification requires sha256sum or shasum.' >&2
        exit 1
    fi

    releases=https://github.com/aakarim/OpenLore/releases
    if [ "$version" = latest ]; then
        # Resolve once so the archive and checksum always come from the same release.
        release_url=$(curl --proto '=https' --tlsv1.2 -fsSL --retry 2 -o /dev/null -w '%{url_effective}' "$releases/latest")
        version=${release_url##*/}
    fi
    case "$version" in v*) ;; *) version=v$version ;; esac
    case "$version" in
        v[0-9]*) ;;
        *) echo 'Invalid release version.' >&2; exit 1 ;;
    esac
    case "$version" in *[!a-zA-Z0-9.+-]*) echo 'Invalid release version.' >&2; exit 1 ;; esac
    case "$install_dir" in /*) ;; *) echo '--install-dir must be an absolute path.' >&2; exit 1 ;; esac

    work=$(mktemp -d)
    staged=
    trap 'rm -rf "$work"; if [ -n "$staged" ]; then rm -f "$staged"; fi' 0
    trap 'exit 1' HUP INT TERM
    archive=openlore_${os}_${arch}.tar.gz
    echo "Downloading OpenLore $version ($os/$arch)..."
    curl --proto '=https' --tlsv1.2 -fsSL --retry 2 "$releases/download/$version/$archive" -o "$work/$archive"
    curl --proto '=https' --tlsv1.2 -fsSL --retry 2 "$releases/download/$version/checksums.txt" -o "$work/checksums.txt"
    expected=$(awk -v name="$archive" '$2 == name { print $1 }' "$work/checksums.txt")
    [ "${#expected}" -eq 64 ] || { echo 'Missing or invalid release checksum.' >&2; exit 1; }
    case "$expected" in *[!0-9a-fA-F]*) echo 'Invalid release checksum.' >&2; exit 1 ;; esac
    if [ "$checksum_tool" = sha256sum ]; then
        actual=$(sha256sum "$work/$archive" | awk '{print $1}')
    else
        actual=$(shasum -a 256 "$work/$archive" | awk '{print $1}')
    fi
    [ "$actual" = "$expected" ] || { echo 'Checksum mismatch. Nothing was installed.' >&2; exit 1; }

    # Require exactly one regular executable entry, not links, directories or duplicates.
    entry=$(tar -tvzf "$work/$archive" openlore)
    [ "$(printf '%s\n' "$entry" | awk '{ print substr($0, 1, 1) }')" = '-' ] || {
        echo 'Release archive must contain exactly one regular openlore file.' >&2
        exit 1
    }
    mkdir -p "$install_dir"
    staged=$(mktemp "$install_dir/.openlore.XXXXXX")
    # Stream bytes only: tar never creates archive-controlled paths or links on disk.
    tar -xzOf "$work/$archive" openlore > "$staged"
    chmod 755 "$staged"
    mv -f "$staged" "$install_dir/openlore"
    staged=
    echo "Installed OpenLore $version to $install_dir/openlore"
    case ":${PATH:-}:" in
        *":$install_dir:"*) ;;
        *) printf '\nAdd this directory to your PATH in your shell configuration:\n  export PATH="%s:$PATH"\n' "$install_dir" ;;
    esac
    echo 'Next: openlore ./docs'
}

main "$@"
