#!/bin/bash
set -e

# ================= USER FLAGS =================
MANAGE_PROTON_GE=true
MANAGE_LUXTORPEDA=true
# ==============================================

# ============================================================
# Dependency checks
# ============================================================

REQUIRED_CMDS=(rsync curl jq tar awk sed)

for cmd in "${REQUIRED_CMDS[@]}"; do
    if ! command -v "$cmd" >/dev/null 2>&1; then
        echo "❌ Required command not found: $cmd"
        echo "Please install it and run the script again."
        exit 1
    fi
done

INSTALL_BASE="$HOME/.steam/steam/compatibilitytools.d"
TEMP_DIR="$(mktemp -d)"

mkdir -p "$INSTALL_BASE"

echo "Fetching all Steam Play release data from GitHub..."

# ============================================================
# Version detection
# ============================================================

declare -A VERSION_EXCEPTIONS=(
    ["1707701731 GE-Proton8-31-4-gdfe728b4"]="8-32"
)

is_version_installed() {
    local dir="$1"
    local expected="$2"

    local version_txt="$dir/version.txt"
    local version_py="$dir/version.py"
    local version_file="$dir/version"

    if [[ -f "$version_txt" ]]; then
        [[ "$(cat "$version_txt")" == "$expected" ]]
        return
    fi

    if [[ -f "$version_py" ]]; then
        local v
        v=$(grep -E "^VERSION\s*=" "$version_py" | sed -E "s/.*['\"]([^'\"]+)['\"].*/\1/")
        [[ "${v#v}" == "${expected#v}" ]]
        return
    fi

    if [[ -f "$version_file" ]]; then
        local raw
        raw=$(cat "$version_file")

        if [[ -n "${VERSION_EXCEPTIONS[$raw]}" ]]; then
            raw="${VERSION_EXCEPTIONS[$raw]}"
        else
            raw=$(echo "$raw" | sed -E 's/^[0-9]+[[:space:]]+//')
            if [[ "$raw" =~ ([0-9]+-[0-9]+) ]]; then
                raw="${BASH_REMATCH[1]}"
            fi
        fi

        [[ "$raw" == "$expected" ]]
        return
    fi

    return 1
}

get_latest_tag() {
    local repo="$1"
    local pattern="$2"
    local transform="$3"

    git ls-remote --tags "$repo" 2>/dev/null \
        | awk -F/ '{print $3}' \
        | sed 's/\^{}//' \
        | grep -E "$pattern" \
        | sed -E "$transform" \
        | sort -V \
        | tail -n1
}

# ============================================================
# Install helper
# ============================================================

download_and_install() {

    local url="$1"
    local target="$2"
    local version="$3"

    local name
    name=$(basename "$target")
    local display_name="$name"

    if [[ "$name" == *-Latest ]]; then
        internal_name="$name"
    else
        if [[ "$name" =~ ^(.+?)([0-9]+)- ]]; then
            internal_name="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
        elif [[ "$name" =~ ^(.+?-)([0-9]+)\. ]]; then
            internal_name="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
        else
            internal_name="$name"
        fi

        target="$(dirname "$target")/$internal_name"
        name="$internal_name"
    fi

    if is_version_installed "$target" "$version"; then
        local name
        name=$(basename "$target")

        local display_version="$version"
        if [[ "$name" == *Proton* ]]; then
            display_version="v$version"
        fi

        echo "✔ $name is already up to date (version $display_version)."
        return
    fi

    echo "⬇ Installing $version to $target"

    local file="$TEMP_DIR/$(basename "$url")"
    curl -fL -o "$file" "$url"

    local stage
    stage=$(mktemp -d "$TEMP_DIR/stage.XXXX")

    tar -xf "$file" -C "$stage"

    local src
    src=$(find "$stage" -mindepth 1 -maxdepth 1 -type d | head -n1)

    local tmp
    tmp=$(mktemp -d "$TEMP_DIR/tmp.XXXX")

    cp -a "$src/." "$tmp/"

    local name
    name=$(basename "$target")

    if [[ -f "$tmp/compatibilitytool.vdf" ]]; then
        sed -i -E 's/("display_name"[[:space:]]+")[^"]+"/\1'"$display_name"'"/' "$tmp/compatibilitytool.vdf"

        # Apply internal name rewrite
        awk -v name="$internal_name" '
        /"compat_tools"/ {
            print
            getline
            print
            getline
            sub(/"[^"]*"/, "\"" name "\"")
            print
            next
        }
        { print }
        ' "$tmp/compatibilitytool.vdf" > "$tmp/compatibilitytool.vdf.new" \
          && mv "$tmp/compatibilitytool.vdf.new" "$tmp/compatibilitytool.vdf"
    fi

    echo "$version" > "$tmp/version.txt"

    mkdir -p "$target"

    rsync -a --delete "$tmp/" "$target/"

    rm -rf "$tmp"
    rm -rf "$stage"
    rm -f "$file"

    echo "✅ Installed $name (version $version)"
}

# ============================================================
# Proton-GE
# ============================================================

get_proton_ge_majors_git() {
    git ls-remote --tags \
        https://github.com/GloriousEggroll/proton-ge-custom.git 2>/dev/null |
        awk -F/ '
            $3 ~ /^GE-Proton[0-9]+-[0-9]+(\^\{\})?$/ {
                gsub(/\^\{\}$/, "", $3)
                print $3
            }
        ' |
        sort -Vu |
        grep -E '^GE-Proton[0-9]+-[0-9]+$' |
        sed -E 's/^GE-Proton//' |
        awk -F- '$1 >= 11' |
        awk -F- '
            {
                major=$1
                latest[major]=$0
            }
            END {
                for (major in latest)
                    print major "|" latest[major]
            }
        '
}

manage_proton_ge() {

    local repo="https://github.com/GloriousEggroll/proton-ge-custom.git"
    local repo_api="https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/tags"

    declare -A git_versions
    local highest_major=0

    while IFS="|" read -r major version; do
        git_versions["$major"]="$version"

        if (( major > highest_major )); then
            highest_major="$major"
        fi
    done < <(get_proton_ge_majors_git)

    # If git failed, fall back to API immediately
    if [[ ${#git_versions[@]} -eq 0 ]]; then
        echo "⚠ Failed to fetch git tags, falling back to API..."

        local releases
        releases=$(curl -s "https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases?per_page=1000")

        mapfile -t urls < <(
            echo "$releases" |
            jq -r '.[] | .assets[] | select(.name | endswith("-x86_64.tar.gz")) | .browser_download_url'
        )

        declare -A latest_by_major

        local latest_version=""
        local latest_url=""

        for url in "${urls[@]}"; do

            local file
            file=$(basename "$url")

            if [[ "$file" =~ ^GE-Proton([0-9]+)-([0-9]+)-x86_64\.tar\.gz$ ]]; then

                local major="${BASH_REMATCH[1]}"
                local minor="${BASH_REMATCH[2]}"
                local version="$major-$minor"

                if (( major < 11 )); then
                    continue
                fi

                local current="${latest_by_major[$major]%%|*}"

                if [[ -z "$current" || "$(printf "%s\n%s\n" "$current" "$version" | sort -V | tail -n1)" == "$version" ]]; then
                    latest_by_major["$major"]="$version|$url"
                fi

                if [[ -z "$latest_version" || "$(printf "%s\n%s\n" "$latest_version" "$version" | sort -V | tail -n1)" == "$version" ]]; then
                    latest_version="$version"
                    latest_url="$url"
                fi
            fi
        done

        [[ -z "$latest_url" ]] && return

        download_and_install "$latest_url" "$INSTALL_BASE/GE-Proton-Latest" "$latest_version"

        for major in "${!latest_by_major[@]}"; do

            entry="${latest_by_major[$major]}"
            version="${entry%%|*}"
            url="${entry##*|}"

            [[ "$version" == "$latest_version" ]] && continue

            download_and_install "$url" "$INSTALL_BASE/GE-Proton$version" "$version"
        done

        return
    fi

    # Git successfully found the versions.
    # Only query the GitHub API for releases that actually need updating.

    declare -A needs_update

    for major in "${!git_versions[@]}"; do

        local version="${git_versions[$major]}"

        if (( major == highest_major )); then
            if ! is_version_installed "$INSTALL_BASE/GE-Proton-Latest" "$version"; then
                needs_update["$major"]="$version|$INSTALL_BASE/GE-Proton-Latest"
            fi
        else
            if ! is_version_installed "$INSTALL_BASE/GE-Proton$version" "$version"; then
                needs_update["$major"]="$version|$INSTALL_BASE/GE-Proton$version"
            fi
        fi
    done

    # Everything is current — no GitHub API request.
    if [[ ${#needs_update[@]} -eq 0 ]]; then
        for major in $(printf "%s\n" "${!git_versions[@]}" | sort -rn); do
            local version="${git_versions[$major]}"

            if (( major == highest_major )); then
                echo "✔ GE-Proton-Latest is already up to date (version v$version)."
            else
                echo "✔ GE-Proton$major is already up to date (version v$version)."
            fi
        done

        return
    fi

    # Fetch the GitHub release API only for versions that need updating.
    for major in "${!needs_update[@]}"; do

        local entry="${needs_update[$major]}"
        local version="${entry%%|*}"
        local target="${entry##*|}"

        echo "Fetching GitHub download URL for GE-Proton$version..."

        local release_json
        release_json=$(curl -fsSL \
            "$repo_api/GE-Proton$version") || {
                echo "❌ Failed to fetch GitHub release for GE-Proton$version."
                return 1
            }

        local url
        url=$(echo "$release_json" |
            jq -r '
                .assets[]
                | select(.name | endswith("-x86_64.tar.gz"))
                | .browser_download_url
            ' |
            head -n1)

        if [[ -z "$url" || "$url" == "null" ]]; then
            echo "❌ Could not find x86_64 tar.gz asset for GE-Proton$version."
            return 1
        fi

        download_and_install "$url" "$target" "$version"
    done
}

manage_proton_ge_legacy() {

    V7_GE_LEGACY_LIST=(
        "10-34|https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton10-34/GE-Proton10-34.tar.gz"
        "9-27|https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton9-27/GE-Proton9-27.tar.gz"
        "8-32|https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton8-32/GE-Proton8-32.tar.gz"
        "7-55|https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-55/GE-Proton7-55.tar.gz"
    )

    for item in "${V7_GE_LEGACY_LIST[@]}"; do
        IFS="|" read -r v u <<< "$item"
        download_and_install "$u" "$INSTALL_BASE/GE-Proton$v" "$v"
    done

    V4_GE_LEGACY_LIST=(
        "6.21-GE-2|https://github.com/GloriousEggroll/proton-ge-custom/releases/download/6.21-GE-2/Proton-6.21-GE-2.tar.gz"
        "5.9-GE-8-ST|https://github.com/GloriousEggroll/proton-ge-custom/releases/download/5.9-GE-8-ST/Proton-5.9-GE-8-ST.tar.gz"
	"4.21-GE-2|https://github.com/GloriousEggroll/proton-ge-custom/releases/download/4.21-GE-2/Proton-4.21-GE-2.tar.gz"
    )

    for item in "${V4_GE_LEGACY_LIST[@]}"; do
        IFS="|" read -r v u <<< "$item"

        major="${v%%.*}"
        patch=$(echo "$v" | cut -d '.' -f2 | cut -d '-' -f1)

        download_and_install "$u" "$INSTALL_BASE/GE-Proton$major-$patch" "$v"
    done
}

# ============================================================
# Luxtorpeda
# ============================================================

manage_luxtorpeda() {

    local repo="https://github.com/luxtorpeda-dev/luxtorpeda.git"

    latest_v=$(get_latest_tag "$repo" '^v[0-9]+\.[0-9]+\.[0-9]+$' 's/^/ /;s/^ //')

    if [[ -n "$latest_v" ]] && is_version_installed "$INSTALL_BASE/Luxtorpeda-Latest" "$latest_v"; then
        echo "✔ Luxtorpeda-Latest is already up to date (version $latest_v)."
        return
    fi

    # Use GitHub API for the update
    LUX_DATA=$(curl -s "https://api.github.com/repos/luxtorpeda-dev/luxtorpeda/releases?per_page=100")

    mapfile -t LUX_URLS < <(echo "$LUX_DATA" | grep browser_download_url | grep '\.tar\.xz"' | cut -d '"' -f4)

    latest_v=""
    latest_u=""

    for u in "${LUX_URLS[@]}"; do

        f=$(basename "$u")

        [[ "$f" =~ luxtorpeda-(v[0-9]+\.[0-9]+\.[0-9]+)\.tar\.xz ]] || continue

        v="${BASH_REMATCH[1]}"

        if [[ -z "$latest_v" || "$(printf "%s\n%s\n" "$latest_v" "$v" | sort -V | tail -n1)" == "$v" ]]; then
            latest_v="$v"
            latest_u="$u"
        fi
    done

    download_and_install "$latest_u" "$INSTALL_BASE/Luxtorpeda-Latest" "$latest_v"
}

# ============================================================
# Run handlers
# ============================================================

[[ "$MANAGE_PROTON_GE" == true ]] && manage_proton_ge
[[ "$MANAGE_PROTON_GE" == true ]] && manage_proton_ge_legacy
[[ "$MANAGE_LUXTORPEDA" == true ]] && manage_luxtorpeda

# ============================================================
# Cleanup
# ============================================================

rm -rf "$TEMP_DIR"

echo "✅ All Steam Play versions are now up to date!"
