#!/usr/bin/env bash
# samcommand official installer for Linux/macOS
# Usage:  curl -fsSL https://samai.cc/samcommand/downloads/install.sh | bash
#   or:   curl -fsSL https://samai.cc/samcommand/downloads/install.sh | bash -s -- --version v1.4.1
#
# Downloads the samcommand binary for the current platform to
# /usr/local/bin/samcommand (or ~/.local/bin/samcommand without sudo).
#
# v1.4.2 improvements:
#   - Reads latest-version.txt to know which version is being installed.
#   - Verifies SHA256 against checksums-sha256.txt after download.
#   - Falls back to no-checksum-verify if the checksums file is unreachable.
#   - Prints a clear "Installed: samcommand vX.Y.Z" line at the end.

set -euo pipefail
BASE_URL="https://samai.cc/samcommand/downloads"
INSTALL_DIR="/usr/local/bin"
BIN_NAME="samcommand"

# Optional --version override (otherwise use latest-version.txt).
REQUESTED_VERSION=""
while [[ $# -gt 0 ]]; do
    case "$1" in
        --version) REQUESTED_VERSION="$2"; shift 2 ;;
        --no-verify) NO_VERIFY=1; shift ;;
        *) echo "Unknown option: $1" >&2; exit 1 ;;
    esac
done

OS="$(uname -s)"
ARCH="$(uname -m)"
case "$OS" in
    Linux*)  PLATFORM_OS="linux" ;;
    Darwin*) PLATFORM_OS="darwin" ;;
    *) echo "Unsupported OS: $OS" >&2; exit 1 ;;
esac
case "$ARCH" in
    x86_64|amd64)   PLATFORM_ARCH="amd64" ;;
    aarch64|arm64)  PLATFORM_ARCH="arm64" ;;
    armv7l|armv6l|arm) PLATFORM_ARCH="arm" ;;
    *) echo "Unsupported architecture: $ARCH" >&2; exit 1 ;;
esac

PLATFORM="${PLATFORM_OS}-${PLATFORM_ARCH}"
REMOTE_FILE="samcommand-${PLATFORM}"
echo "Detected platform: $PLATFORM"

# Fetch the latest version label (for display only — the binary URL is
# unversioned, the server always serves the latest at that path).
if [[ -z "$REQUESTED_VERSION" ]]; then
    REQUESTED_VERSION="$(curl -fsSL --max-time 10 "$BASE_URL/latest-version.txt" 2>/dev/null || echo unknown)"
fi
echo "Latest version:   $REQUESTED_VERSION"

SUDO=""
if [[ -w "$INSTALL_DIR" ]]; then
    TARGET="${INSTALL_DIR}/${BIN_NAME}"
elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
    TARGET="${INSTALL_DIR}/${BIN_NAME}"
    SUDO="sudo"
else
    TARGET="${HOME}/.local/bin/${BIN_NAME}"
    mkdir -p "$(dirname "$TARGET")"
    echo "No sudo access - installing to $TARGET" >&2
    echo "Make sure ${HOME}/.local/bin is in your PATH." >&2
fi

TMP_FILE="$(mktemp -t samcommand-XXXXXX)"
trap 'rm -f "$TMP_FILE"' EXIT

URL="${BASE_URL}/${REMOTE_FILE}"
echo "Downloading $URL ..."
# Add cache-busting query param so CDN/proxy caches don't serve stale
# binaries after we publish a new version. The server ignores the param.
curl -fSL --retry 3 --retry-delay 2 -o "$TMP_FILE" "${URL}?t=$(date +%s)"

# SHA256 verification (best-effort).
# Tries multiple tools because not every platform has the same one:
#   - shasum -a 256   (macOS default, also some Linux via perl-Digest-SHA)
#   - sha256sum       (Linux coreutils, Termux default)
#   - openssl dgst -sha256 (commonly available fallback)
#   - python3 -c '...' (last-resort, works everywhere python is installed)
compute_sha256() {
    local file="$1"
    if command -v shasum >/dev/null 2>&1; then
        shasum -a 256 "$file" | awk '{print $1}'
    elif command -v sha256sum >/dev/null 2>&1; then
        sha256sum "$file" | awk '{print $1}'
    elif command -v openssl >/dev/null 2>&1; then
        openssl dgst -sha256 "$file" | awk '{print $NF}'
    elif command -v python3 >/dev/null 2>&1; then
        python3 -c "import hashlib; print(hashlib.sha256(open('$file','rb').read()).hexdigest())"
    elif command -v python >/dev/null 2>&1; then
        python -c "import hashlib; print(hashlib.sha256(open('$file','rb').read()).hexdigest())"
    else
        return 1
    fi
}

if [[ -z "${NO_VERIFY:-}" ]]; then
    echo "Verifying SHA256 ..."
    ACTUAL_SHA="$(compute_sha256 "$TMP_FILE")"
    if [[ -z "$ACTUAL_SHA" ]]; then
        echo "  [warn] no SHA256 tool found (tried shasum, sha256sum, openssl, python3, python); skipping verification."
        echo "  To install one:  pkg install coreutils  (Termux)  |  apt install coreutils  (Linux)  |  brew install perl  (macOS)"
    else
        # Try to fetch the expected SHA from the server's checksums file.
        EXPECTED_SHA="$(curl -fsSL --max-time 10 "$BASE_URL/checksums-sha256.txt" 2>/dev/null | awk -v f="$REMOTE_FILE" '$2==f {print $1; exit}')"
        if [[ -z "$EXPECTED_SHA" ]]; then
            echo "  [warn] could not fetch checksums-sha256.txt; skipping verification."
        elif [[ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]]; then
            echo "  [ERROR] SHA256 mismatch!" >&2
            echo "    expected: $EXPECTED_SHA" >&2
            echo "    actual:   $ACTUAL_SHA" >&2
            echo "    file:     $REMOTE_FILE" >&2
            echo "  Aborting. The downloaded binary is corrupted or has been tampered with." >&2
            exit 1
        else
            echo "  [ok] SHA256 matches ($ACTUAL_SHA)"
        fi
    fi
fi

if [[ -n "$SUDO" ]]; then
    $SUDO install -m 0755 "$TMP_FILE" "$TARGET"
else
    install -m 0755 "$TMP_FILE" "$TARGET"
fi

# On macOS, strip the com.apple.quarantine extended attribute so the first
# run doesn't pop up the "downloaded from the internet" Gatekeeper dialog.
if [[ "$PLATFORM_OS" == "darwin" ]]; then
    if command -v xattr >/dev/null 2>&1; then
        xattr -d com.apple.quarantine "$TARGET" 2>/dev/null || true
    fi
fi

# ---- Also install aitun-client (the tunnel client samcommand depends on) ----
# Without this, the first `samcommand` run has to download aitun-client itself,
# which is slow and confusing ("why is it downloading again?"). We pre-install
# it here so samcommand can start instantly.
#
# aitun-client is hosted on aitun.cc (separate product), platform naming:
#   aitun-client-{os}-{arch}[.exe]
# It lives in ~/.samcommand/ (samcommand's data dir), NOT in /usr/local/bin,
# because samcommand looks for it there.
AITUN_DATA_DIR="${HOME}/.samcommand"
AITUN_REMOTE="aitun-client-${PLATFORM}"
# Windows binary has .exe suffix
if [[ "$PLATFORM_OS" == "windows" ]]; then
    AITUN_REMOTE="aitun-client-${PLATFORM_OS}-${PLATFORM_ARCH}.exe"
fi
AITUN_TARGET="${AITUN_DATA_DIR}/${AITUN_REMOTE}"

mkdir -p "$AITUN_DATA_DIR"

# Skip if already exists and is executable (re-running install.sh shouldn't
# re-download unless forced).
if [[ -x "$AITUN_TARGET" ]] && [[ "${FORCE:-0}" != "1" ]]; then
    echo "aitun-client already installed at $AITUN_TARGET (skip)"
else
    AITUN_URL="https://aitun.cc/downloads/${AITUN_REMOTE}"
    echo "Downloading aitun-client (tunnel client) ..."
    if curl -fSL --retry 3 --retry-delay 2 -o "$AITUN_TARGET" "${AITUN_URL}?t=$(date +%s)" 2>&1; then
        chmod 0755 "$AITUN_TARGET"
        AITUN_SIZE=$(wc -c < "$AITUN_TARGET" | tr -d ' ')
        echo "  [ok] aitun-client installed ($AITUN_SIZE bytes) -> $AITUN_TARGET"
    else
        echo "  [warn] could not download aitun-client from $AITUN_URL"
        echo "  samcommand will download it automatically on first run."
        rm -f "$AITUN_TARGET"
    fi
fi

# Report the actual installed version by querying the binary's /info or
# --help output. The /info endpoint reports "version" in JSON.
VERSION_OUT="$("$TARGET" --help 2>&1 | head -1 || true)"
echo "Installed: $VERSION_OUT"
echo
echo "Done! Try it now:"
echo "    samcommand --help"
echo "    samcommand --no-tunnel --verbose   # local-only test mode"
echo "    samcommand --no-p2p --verbose      # full mode with tunnel (aitun-client pre-installed)"
