#!/usr/bin/env bash
set -euo pipefail

STATIC_BASE_URL="${BOT_FORGE_BASE_URL:-}"
STATIC_BASE_URL="${STATIC_BASE_URL%/}"
RELEASE_TAG="${BOT_FORGE_RELEASE_TAG:-v1.0.2}"
RELEASE_ATTACHMENTS_BASE_URL="https://api.gitcode.com/api/v5/repos/xuanwu/bot-forge/releases/${RELEASE_TAG}/attach_files"
CHECKSUMS_RELATIVE_PATH="SHA256SUMS"
CHECKSUMS_SHA256="${BOT_FORGE_CHECKSUMS_SHA256:-}"
CONFIG_RELATIVE_PATH="bot-forge.toml"

case "$(uname -s)" in
Linux)
    OS="linux"
    DEFAULT_DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/bot-forge"
    DEFAULT_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/bot-forge"
    DEFAULT_BIN_DIR="$HOME/.local/bin"
    ;;
Darwin)
    OS="macos"
    DEFAULT_DATA_DIR="$HOME/Library/Application Support/bot-forge"
    DEFAULT_CONFIG_DIR="$HOME/Library/Application Support/bot-forge/config"
    DEFAULT_BIN_DIR="$DEFAULT_DATA_DIR/bin"
    ;;
*)
    printf 'bot-forge 安装脚本仅支持 Linux 和 macOS。\n' >&2
    exit 1
    ;;
esac

DATA_DIR="${BOT_FORGE_HOME:-$DEFAULT_DATA_DIR}"
CONFIG_DIR="${BOT_FORGE_CONFIG_DIR:-$DEFAULT_CONFIG_DIR}"
BIN_DIR="${BOT_FORGE_BIN_DIR:-${BOT_FORGE_HOME:+$DATA_DIR/bin}}"
BIN_DIR="${BIN_DIR:-$DEFAULT_BIN_DIR}"

MACHINE_ARCH="$(uname -m)"
if [[ "$OS" == "macos" ]] && command -v sysctl >/dev/null 2>&1; then
    if [[ "$(sysctl -in sysctl.proc_translated 2>/dev/null || true)" == "1" ]] ||
        [[ "$(sysctl -n hw.optional.arm64 2>/dev/null || true)" == "1" ]]; then
        MACHINE_ARCH="arm64"
    fi
fi

case "$MACHINE_ARCH" in
x86_64 | amd64) ARCH="x86_64" ;;
aarch64 | arm64) ARCH="aarch64" ;;
*)
    printf '不支持的 %s 架构：%s\n' "$OS" "$MACHINE_ARCH" >&2
    exit 1
    ;;
esac

PLATFORM="${OS}-${ARCH}"

BINARY_RELATIVE_PATH="${PLATFORM}-bot-forge"
BINARY_PATH="${BIN_DIR}/bot-forge"
CONFIG_PATH="${CONFIG_DIR}/bot-forge.toml"
TEMP_DIR="$(mktemp -d)"
BINARY_STAGE=""
CONFIG_STAGE=""
CONFIG_BACKUP_STAGE=""
trap 'rm -rf "$TEMP_DIR"; [[ -z "$BINARY_STAGE" ]] || rm -f "$BINARY_STAGE"; [[ -z "$CONFIG_STAGE" ]] || rm -f "$CONFIG_STAGE"; [[ -z "$CONFIG_BACKUP_STAGE" ]] || rm -f "$CONFIG_BACKUP_STAGE"' EXIT

download() {
    local relative_path="$1"
    local destination="$2"
    local url

    if [[ -n "$STATIC_BASE_URL" ]]; then
        url="${STATIC_BASE_URL}/${relative_path}"
    else
        url="${RELEASE_ATTACHMENTS_BASE_URL}/${relative_path}/download"
    fi

    curl --fail --show-error --silent --location "$url" -o "$destination"
}

checksum_for() {
    local relative_path="$1"
    awk -v target="$relative_path" '
        length($1) == 64 && $1 ~ /^[[:xdigit:]]+$/ {
            path = $2
            sub(/^\*/, "", path)
            sub(/\r$/, "", path)
            if (path == target) {
                print tolower($1)
                exit
            }
        }
    ' "$TEMP_DIR/SHA256SUMS"
}

sha256_for() {
    local path="$1"
    if command -v sha256sum >/dev/null 2>&1; then
        sha256sum "$path" | awk '{print tolower($1)}'
    elif command -v shasum >/dev/null 2>&1; then
        shasum -a 256 "$path" | awk '{print tolower($1)}'
    else
        printf '未找到 sha256sum 或 shasum，无法校验下载文件。\n' >&2
        exit 1
    fi
}

verify() {
    local relative_path="$1"
    local path="$2"
    local expected actual
    expected="$(checksum_for "$relative_path")"
    if [[ -z "$expected" ]]; then
        printf 'SHA256SUMS 中缺少 %s 的校验值。\n' "$relative_path" >&2
        exit 1
    fi
    actual="$(sha256_for "$path")"
    if [[ "$actual" != "$expected" ]]; then
        printf '文件校验失败：%s\n' "$relative_path" >&2
        exit 1
    fi
}

printf '正在下载 bot-forge（%s）...\n' "$PLATFORM"
download "$CHECKSUMS_RELATIVE_PATH" "$TEMP_DIR/SHA256SUMS"
if [[ ! "$CHECKSUMS_SHA256" =~ ^[[:xdigit:]]{64}$ ]]; then
    printf '必须通过 BOT_FORGE_CHECKSUMS_SHA256 提供可信的 SHA256SUMS 摘要。\n' >&2
    exit 1
fi
CHECKSUMS_SHA256_NORMALIZED="$(printf '%s' "$CHECKSUMS_SHA256" | tr '[:upper:]' '[:lower:]')"
if [[ "$(sha256_for "$TEMP_DIR/SHA256SUMS")" != "$CHECKSUMS_SHA256_NORMALIZED" ]]; then
    printf 'SHA256SUMS 发布摘要校验失败。\n' >&2
    exit 1
fi
download "$BINARY_RELATIVE_PATH" "$TEMP_DIR/bot-forge"
download "$CONFIG_RELATIVE_PATH" "$TEMP_DIR/bot-forge.toml"

verify "$BINARY_RELATIVE_PATH" "$TEMP_DIR/bot-forge"
verify "$CONFIG_RELATIVE_PATH" "$TEMP_DIR/bot-forge.toml"

mkdir -p "$BIN_DIR" "$DATA_DIR" "$CONFIG_DIR"
BINARY_STAGE="$(mktemp "$BIN_DIR/.bot-forge.new.XXXXXX")"
install -m 755 "$TEMP_DIR/bot-forge" "$BINARY_STAGE"
mv -f "$BINARY_STAGE" "$BINARY_PATH"
BINARY_STAGE=""

printf '正在验证服务器下发的云端配置...\n'
"$BINARY_PATH" config validate --config "$TEMP_DIR/bot-forge.toml"

if [[ -e "$CONFIG_PATH" ]]; then
    CONFIG_BACKUP_PATH="${CONFIG_PATH}.bot-forge.bak"
    CONFIG_BACKUP_STAGE="$(mktemp "$CONFIG_DIR/.bot-forge.toml.backup.XXXXXX")"
    cp -p "$CONFIG_PATH" "$CONFIG_BACKUP_STAGE"
    mv -f "$CONFIG_BACKUP_STAGE" "$CONFIG_BACKUP_PATH"
    CONFIG_BACKUP_STAGE=""
    printf '已有配置已备份：%s\n' "$CONFIG_BACKUP_PATH"
fi

CONFIG_STAGE="$(mktemp "$CONFIG_DIR/.bot-forge.toml.new.XXXXXX")"
install -m 644 "$TEMP_DIR/bot-forge.toml" "$CONFIG_STAGE"
mv -f "$CONFIG_STAGE" "$CONFIG_PATH"
CONFIG_STAGE=""
printf '云端配置已写入：%s\n' "$CONFIG_PATH"

printf '下载和校验完成，开始运行 bot-forge。\n'
exec "$BINARY_PATH" install --config "$CONFIG_PATH" "$@"
