#!/bin/bash

# YABS Wrapper Script (Login ServerVerify) — Alpine Linux Edition
# Handles IPv6-only systems, low memory configurations, and ServerVerify API integration
# Authenticates to ServerVerify via username/password instead of browser cookies
#
# Alpine-specific features:
#   - Installs required packages (bash, GNU grep, fio, iperf3, docker, etc.)
#   - Runs Geekbench inside a Debian Docker container (Geekbench requires glibc)
#   - Uses pure-bash URL decoding (no python3 dependency)
#   - Falls back to /proc/meminfo if `free` is unavailable
#
# Usage: ./yabs_wrapper_login_alpine.sh [OPTIONS]
#   -e, --email EMAIL          Geekbench Pro email
#   -k, --key KEY              Geekbench Pro license key
#   -s, --server URL           ServerVerify API URL (skip auto-creation)
#   -p, --provider NAME        Provider name to search for on ServerVerify
#   -u, --username EMAIL       ServerVerify login email
#   --password PASS            ServerVerify login password
#   --private                  Keep the benchmark report private
#   --cost AMOUNT              Service cost in USD
#   --billing monthly|quarterly|yearly  Billing interval
#   --recommend yes|no         Whether you recommend the service
#   --no-serververify          Skip ServerVerify entirely
#   --skip-fio                 Skip fio disk benchmarks
#   --skip-iperf               Skip iperf network benchmarks
#   -h, --help                 Show this help message

# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# --- Alpine Linux support functions ---

# Detect if running on Alpine Linux
is_alpine() {
    [ -f /etc/alpine-release ]
}

# Snapshot file: tracks packages installed before we add ours, so cleanup
# only removes what we added (not pre-existing packages).
APK_SNAPSHOT="/tmp/apk_snapshot_$$"

# Install required packages on Alpine
install_alpine_deps() {
    if ! is_alpine; then
        return 0
    fi

    echo -e "${YELLOW}Alpine Linux detected ($(cat /etc/alpine-release))${NC}"
    echo -e "${YELLOW}Installing required packages...${NC}"

    # Snapshot currently installed packages so cleanup knows what to remove
    apk info -q 2>/dev/null | sort > "$APK_SNAPSHOT"

    # Docker lives in the community repo — enable it if not already
    if ! grep -q '^[^#].*/community$' /etc/apk/repositories 2>/dev/null; then
        echo -e "${YELLOW}Enabling Alpine community repository (required for Docker)...${NC}"
        local alpine_ver
        alpine_ver=$(cat /etc/alpine-release | cut -d. -f1,2)
        echo "https://dl-cdn.alpinelinux.org/alpine/v${alpine_ver}/community" >> /etc/apk/repositories
        apk update
    fi

    apk add --no-cache \
        bash \
        curl \
        jq \
        grep \
        coreutils \
        util-linux \
        procps-ng \
        fio \
        iperf3 \
        docker

    # Start Docker daemon if not running
    if ! docker info &>/dev/null; then
        echo -e "${YELLOW}Starting Docker daemon...${NC}"
        service docker start 2>/dev/null || rc-service docker start 2>/dev/null || true
        # Wait for Docker to be ready (up to 15 seconds)
        local tries=0
        while ! docker info &>/dev/null && [ $tries -lt 15 ]; do
            sleep 1
            tries=$((tries + 1))
        done
        if docker info &>/dev/null; then
            echo -e "${GREEN}Docker daemon started${NC}"
        else
            echo -e "${RED}Failed to start Docker daemon — Geekbench will not work${NC}"
        fi
    fi

    # Pre-pull the Debian slim image so it's ready for the Geekbench Docker wrapper
    if docker info &>/dev/null; then
        if ! docker image inspect gb-runner:latest &>/dev/null; then
            echo -e "${YELLOW}Pulling Debian slim image for Geekbench...${NC}"
            docker pull debian:bookworm-slim 2>/dev/null
        else
            echo -e "${GREEN}Geekbench Docker image already prepared${NC}"
        fi
    fi

    echo -e "${GREEN}Alpine packages installed${NC}"
}

# URL-decode a percent-encoded string (pure bash, no python3 needed)
urldecode() {
    local encoded="$1"
    encoded="${encoded//+/ }"
    printf '%b' "${encoded//%/\\x}"
}

# --- End Alpine support functions ---

# Variables
SWAP_FILE=""
SWAP_SIZE="1G"
SWAP_CREATED=false
GB_EMAIL=""
GB_KEY=""
API_URL=""
SV_PROVIDER=""
SV_USERNAME=""
SV_PASSWORD=""
SV_COOKIEJAR="/tmp/sv_cookiejar_$$"
SV_PRIVATE=""
SV_COST=""
SV_BILLING=""
SV_RECOMMEND=""
NO_SERVERVERIFY=false
SKIP_FIO=false
SKIP_IPERF=false

# Parse command line arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        -e|--email)
            GB_EMAIL="$2"
            shift 2
            ;;
        -k|--key)
            GB_KEY="$2"
            shift 2
            ;;
        -s|--server)
            API_URL="$2"
            shift 2
            ;;
        -p|--provider)
            SV_PROVIDER="$2"
            shift 2
            ;;
        -u|--username)
            SV_USERNAME="$2"
            shift 2
            ;;
        --password)
            SV_PASSWORD="$2"
            shift 2
            ;;
        --private)
            SV_PRIVATE="1"
            shift
            ;;
        --cost)
            SV_COST="$2"
            shift 2
            ;;
        --billing)
            case "$2" in
                monthly)   SV_BILLING="0" ;;
                quarterly) SV_BILLING="2" ;;
                yearly)    SV_BILLING="1" ;;
                *)
                    echo "Invalid billing interval: $2 (use monthly, quarterly, or yearly)"
                    exit 1
                    ;;
            esac
            shift 2
            ;;
        --recommend)
            case "$2" in
                yes) SV_RECOMMEND="1" ;;
                no)  SV_RECOMMEND="0" ;;
                *)
                    echo "Invalid recommend value: $2 (use yes or no)"
                    exit 1
                    ;;
            esac
            shift 2
            ;;
        --no-serververify)
            NO_SERVERVERIFY=true
            shift
            ;;
        --skip-fio)
            SKIP_FIO=true
            shift
            ;;
        --skip-iperf)
            SKIP_IPERF=true
            shift
            ;;
        -h|--help)
            echo "Usage: $0 [OPTIONS]"
            echo ""
            echo "Options:"
            echo "  -e, --email EMAIL          Geekbench Pro email"
            echo "  -k, --key KEY              Geekbench Pro license key"
            echo "  -s, --server URL           ServerVerify API URL (skip auto-creation)"
            echo "  -p, --provider NAME        Provider name to search for on ServerVerify"
            echo "  -u, --username EMAIL       ServerVerify login email"
            echo "  --password PASS            ServerVerify login password"
            echo "  --private                  Keep the benchmark report private"
            echo "  --cost AMOUNT              Service cost in USD"
            echo "  --billing INTERVAL         monthly, quarterly, or yearly"
            echo "  --recommend yes|no         Whether you recommend the service"
            echo "  --no-serververify          Skip ServerVerify entirely"
            echo "  --skip-fio                 Skip fio disk benchmarks"
            echo "  --skip-iperf               Skip iperf network benchmarks"
            echo "  -h, --help                 Show this help message"
            echo ""
            echo "Examples:"
            echo "  $0 -u user@example.com --password secret -p 'BuyVM' -e user@example.com -k LICENSE-KEY"
            echo "  $0 -p 'Hetzner' --private --cost 5.99 --billing monthly --recommend yes"
            echo "  $0 -s https://serververify.com/api/benchmarks/yabs/UUID  # manual URL"
            exit 0
            ;;
        *)
            echo "Unknown option: $1"
            echo "Use -h or --help for usage information"
            exit 1
            ;;
    esac
done

# Cleanup function
cleanup() {
    echo -e "\n${YELLOW}Cleaning up...${NC}"

    # Remove swap file if created
    if [ "$SWAP_CREATED" = true ] && [ -n "$SWAP_FILE" ]; then
        echo "Removing temporary swap file..."
        swapoff "$SWAP_FILE" 2>/dev/null || true
        rm -f "$SWAP_FILE"
    fi

    # Remove license file, temp files, and cookie jar
    rm -f geekbench.license
    rm -f /tmp/sv_response_headers_$$
    rm -f "$SV_COOKIEJAR"
    rm -f /tmp/gb_docker_wrapper.sh

    # Alpine: remove Docker images, stop Docker, and uninstall packages we added
    if is_alpine && [ -f "$APK_SNAPSHOT" ]; then
        echo -e "${YELLOW}Removing Docker images...${NC}"
        docker rmi gb-runner:latest 2>/dev/null || true
        docker rmi debian:bookworm-slim 2>/dev/null || true

        echo -e "${YELLOW}Stopping Docker daemon...${NC}"
        service docker stop 2>/dev/null || rc-service docker stop 2>/dev/null || true

        echo -e "${YELLOW}Removing packages installed by this script...${NC}"
        # Diff current packages against pre-install snapshot to find what we added
        local new_pkgs
        new_pkgs=$(comm -13 "$APK_SNAPSHOT" <(apk info -q 2>/dev/null | sort))
        if [ -n "$new_pkgs" ]; then
            echo "$new_pkgs" | xargs apk del --purge 2>/dev/null || true
        fi
        rm -f "$APK_SNAPSHOT"
    fi

    echo -e "${GREEN}Cleanup complete${NC}"
}

# Set trap to cleanup on exit
trap cleanup EXIT INT TERM

# Function to check if system is IPv6-only
check_ipv6_only() {
    echo -e "${YELLOW}Checking network connectivity...${NC}"

    # Check if we have IPv4 connectivity
    if timeout 3 curl -4 -s -o /dev/null -w "%{http_code}" https://www.google.com 2>/dev/null | grep -q "200"; then
        echo -e "${GREEN}IPv4 connectivity detected${NC}"
        return 1
    fi

    # Check if we have IPv6 connectivity
    if timeout 3 curl -6 -s -o /dev/null -w "%{http_code}" https://www.google.com 2>/dev/null | grep -q "200"; then
        echo -e "${YELLOW}IPv6-only system detected${NC}"
        return 0
    fi

    echo -e "${RED}No connectivity detected${NC}"
    return 2
}

# Function to check available RAM
check_memory() {
    # Get total memory in MB (with /proc/meminfo fallback)
    if command -v free &>/dev/null; then
        TOTAL_MEM=$(free -m | awk '/^Mem:/{print $2}')
    else
        TOTAL_MEM=$(awk '/^MemTotal:/{printf "%d", $2/1024}' /proc/meminfo)
    fi
    echo -e "${YELLOW}Total RAM: ${TOTAL_MEM}MB${NC}"

    if [ "$TOTAL_MEM" -le 1024 ]; then
        echo -e "${YELLOW}Low memory detected (≤1GB)${NC}"
        return 0
    else
        echo -e "${GREEN}Sufficient memory available${NC}"
        return 1
    fi
}

# Function to create temporary swap
create_swap() {
    echo -e "${YELLOW}Creating temporary 1GB swap file...${NC}"

    # Check if we have enough disk space in /tmp
    AVAILABLE_SPACE=$(df /tmp 2>/dev/null | awk 'NR==2 {print $4}')
    if [ -n "$AVAILABLE_SPACE" ] && [ "$AVAILABLE_SPACE" -ge 1048576 ]; then
        SWAP_FILE="/tmp/yabs_swap"
    else
        # Try / instead
        echo -e "${YELLOW}/tmp doesn't have enough space, trying / ...${NC}"
        AVAILABLE_SPACE=$(df / 2>/dev/null | awk 'NR==2 {print $4}')
        if [ -n "$AVAILABLE_SPACE" ] && [ "$AVAILABLE_SPACE" -ge 1048576 ]; then
            SWAP_FILE="/yabs_swap"
        else
            echo -e "${RED}Not enough disk space for swap file${NC}"
            return 1
        fi
    fi

    echo -e "${YELLOW}Creating swap at $SWAP_FILE...${NC}"

    # Create swap file
    dd if=/dev/zero of="$SWAP_FILE" bs=1M count=1024 status=progress
    chmod 600 "$SWAP_FILE"
    mkswap "$SWAP_FILE"
    swapon "$SWAP_FILE"

    SWAP_CREATED=true
    echo -e "${GREEN}Temporary swap file created and activated${NC}"
    free -h 2>/dev/null || awk '/^(Mem|Swap)(Total|Free):/{printf "%s: %d MB\n", $1, $2/1024}' /proc/meminfo
    return 0
}

# Function to prompt for Geekbench Pro license
get_geekbench_license() {
    # If already provided via parameters, skip prompting
    if [ -n "$GB_EMAIL" ] && [ -n "$GB_KEY" ]; then
        echo -e "${GREEN}Using Geekbench Pro license from parameters${NC}"
        echo "$GB_EMAIL $GB_KEY" > geekbench.license
        return 0
    fi

    echo -e "\n${YELLOW}Geekbench Pro License${NC}"
    echo "Do you have a Geekbench Pro license? (y/n)"
    read -r RESPONSE

    if [[ "$RESPONSE" =~ ^[Yy]$ ]]; then
        echo "Please enter your Geekbench Pro email:"
        read -r GB_EMAIL
        echo "Please enter your Geekbench Pro license key:"
        read -r GB_KEY

        if [ -n "$GB_EMAIL" ] && [ -n "$GB_KEY" ]; then
            # Create license file
            echo "$GB_EMAIL $GB_KEY" > geekbench.license
            echo -e "${GREEN}Geekbench Pro license saved${NC}"
            return 0
        else
            echo -e "${YELLOW}License information incomplete, running without Pro features${NC}"
            return 1
        fi
    else
        echo -e "${YELLOW}Running without Geekbench Pro${NC}"
        return 1
    fi
}

# Function to log in to ServerVerify with username/password
# Sets up SV_COOKIEJAR with a valid session
login_serververify() {
    # Prompt for credentials if not provided via flags
    if [ -z "$SV_USERNAME" ]; then
        echo -e "${YELLOW}Enter your ServerVerify email:${NC}"
        read -r SV_USERNAME
        if [ -z "$SV_USERNAME" ]; then
            echo -e "${RED}No username provided${NC}"
            return 1
        fi
    fi
    if [ -z "$SV_PASSWORD" ]; then
        echo -e "${YELLOW}Enter your ServerVerify password:${NC}"
        read -rs SV_PASSWORD
        echo ""
        if [ -z "$SV_PASSWORD" ]; then
            echo -e "${RED}No password provided${NC}"
            return 1
        fi
    fi

    echo -e "${YELLOW}Logging in to ServerVerify...${NC}"

    # Step 1: GET the homepage to get XSRF-TOKEN and session cookies
    curl -s -c "$SV_COOKIEJAR" "https://serververify.com" -o /dev/null 2>/dev/null

    # Extract and URL-decode the XSRF-TOKEN from the cookie jar
    local XSRF_RAW
    XSRF_RAW=$(grep XSRF-TOKEN "$SV_COOKIEJAR" 2>/dev/null | awk '{print $NF}')

    if [ -z "$XSRF_RAW" ]; then
        echo -e "${RED}Failed to get XSRF-TOKEN cookie from ServerVerify${NC}"
        return 1
    fi

    # URL-decode the XSRF token (pure bash — no python3 needed)
    local XSRF_DEC
    XSRF_DEC=$(urldecode "$XSRF_RAW")
    if [ -z "$XSRF_DEC" ]; then
        echo -e "${RED}Failed to decode XSRF-TOKEN${NC}"
        return 1
    fi

    # Step 2: POST /login with credentials (HTMX-style form post)
    local LOGIN_RESPONSE
    LOGIN_RESPONSE=$(curl -s -b "$SV_COOKIEJAR" -c "$SV_COOKIEJAR" \
        -H "X-XSRF-TOKEN: $XSRF_DEC" \
        -H "Accept: application/json" \
        -H "Content-Type: application/json" \
        -H "Referer: https://serververify.com/login" \
        -H "Origin: https://serververify.com" \
        -X POST "https://serververify.com/login" \
        -d "$(jq -n --arg e "$SV_USERNAME" --arg p "$SV_PASSWORD" '{email:$e,password:$p}')" \
        2>/dev/null)

    # Step 3: Check for error message in response
    if echo "$LOGIN_RESPONSE" | grep -qi 'credentials do not match'; then
        echo -e "${RED}Login failed — invalid credentials${NC}"
        return 1
    fi

    # Step 4: Verify we're actually logged in by fetching an authenticated page
    local VERIFY_PAGE
    VERIFY_PAGE=$(curl -s -L -b "$SV_COOKIEJAR" -c "$SV_COOKIEJAR" "https://serververify.com/benchmarks/run" 2>/dev/null)

    if echo "$VERIFY_PAGE" | grep -q 'action="https://serververify.com/logout"'; then
        echo -e "${GREEN}Successfully logged in to ServerVerify${NC}"
        return 0
    fi

    echo -e "${RED}Login failed — could not verify authenticated session${NC}"
    return 1
}

# Function to search for a provider on ServerVerify
# Sets PROVIDER_ID and PROVIDER_NAME on success, returns 1 on failure
# Args: $1 = search term, $2 = CSRF token, $3 = cookies file, $4 = "interactive" to allow selection
search_provider() {
    local SEARCH_TERM="$1"
    local CSRF_TOKEN="$2"
    local COOKIES="$3"
    local INTERACTIVE="$4"

    PROVIDER_ID=""
    PROVIDER_NAME=""

    # Fetch the full provider list from the API
    local ALL_PROVIDERS
    ALL_PROVIDERS=$(curl -s -G -b "$COOKIES" -c "$COOKIES" \
        -H "X-CSRF-TOKEN: $CSRF_TOKEN" \
        -H "Accept: application/json" \
        --data-urlencode "search=$SEARCH_TERM" \
        "https://serververify.com/providers/search" 2>/dev/null)

    if [ -z "$ALL_PROVIDERS" ] || [ "$ALL_PROVIDERS" = "[]" ]; then
        echo -e "${RED}Failed to fetch provider list${NC}"
        return 1
    fi

    # Filter client-side (API returns full list; fields are "id" and "text")
    local FILTERED
    FILTERED=$(echo "$ALL_PROVIDERS" | jq -r \
        --arg term "$SEARCH_TERM" \
        '[.[] | select(.text | test($term; "i"))]')

    local RESULT_COUNT
    RESULT_COUNT=$(echo "$FILTERED" | jq 'length')

    if [ "$RESULT_COUNT" -eq 0 ]; then
        echo -e "${RED}No providers found matching '$SEARCH_TERM'${NC}"
        return 1
    fi

    # Try exact match first (case-insensitive)
    PROVIDER_ID=$(echo "$FILTERED" | jq -r \
        --arg name "$SEARCH_TERM" \
        '[.[] | select(.text | ascii_downcase == ($name | ascii_downcase))][0].id // empty')
    PROVIDER_NAME=$(echo "$FILTERED" | jq -r \
        --arg name "$SEARCH_TERM" \
        '[.[] | select(.text | ascii_downcase == ($name | ascii_downcase))][0].text // empty')

    if [ -n "$PROVIDER_ID" ]; then
        echo -e "${GREEN}Found exact match: $PROVIDER_NAME (ID: $PROVIDER_ID)${NC}"
        return 0
    fi

    # Single result — use it directly
    if [ "$RESULT_COUNT" -eq 1 ]; then
        PROVIDER_ID=$(echo "$FILTERED" | jq -r '.[0].id')
        PROVIDER_NAME=$(echo "$FILTERED" | jq -r '.[0].text')
        echo -e "${GREEN}Found provider: $PROVIDER_NAME (ID: $PROVIDER_ID)${NC}"
        return 0
    fi

    # Multiple results
    if [ "$INTERACTIVE" = "interactive" ]; then
        echo -e "${YELLOW}Multiple providers found:${NC}"
        echo "$FILTERED" | jq -r 'to_entries[] | "  \(.key + 1)) \(.value.text)"'
        echo ""
        echo "Enter the number of the provider to use (or press Enter for #1):"
        read -r SELECTION
        if [ -z "$SELECTION" ]; then
            SELECTION=1
        fi
        if ! [[ "$SELECTION" =~ ^[0-9]+$ ]] || [ "$SELECTION" -lt 1 ] || [ "$SELECTION" -gt "$RESULT_COUNT" ]; then
            echo -e "${RED}Invalid selection${NC}"
            return 1
        fi
        local IDX=$((SELECTION - 1))
        PROVIDER_ID=$(echo "$FILTERED" | jq -r ".[$IDX].id")
        PROVIDER_NAME=$(echo "$FILTERED" | jq -r ".[$IDX].text")
    else
        # Non-interactive: take first result
        PROVIDER_ID=$(echo "$FILTERED" | jq -r '.[0].id')
        PROVIDER_NAME=$(echo "$FILTERED" | jq -r '.[0].text')
    fi

    if [ -n "$PROVIDER_ID" ] && [ "$PROVIDER_ID" != "null" ]; then
        echo -e "${GREEN}Using provider: $PROVIDER_NAME (ID: $PROVIDER_ID)${NC}"
        return 0
    fi

    echo -e "${RED}Failed to extract provider from search results${NC}"
    return 1
}

# Function to automatically create a ServerVerify benchmark and get the API URL
get_serververify_api() {
    # If explicitly disabled, skip
    if [ "$NO_SERVERVERIFY" = true ]; then
        echo -e "${YELLOW}Skipping ServerVerify integration (--no-serververify)${NC}"
        return 1
    fi

    # If already provided via -s parameter, use it directly
    if [ -n "$API_URL" ]; then
        echo -e "${GREEN}Using ServerVerify API URL from parameters: $API_URL${NC}"
        return 0
    fi

    echo -e "\n${YELLOW}ServerVerify Auto-Setup${NC}"

    # Log in to ServerVerify
    if ! login_serververify; then
        echo ""
        echo "Continue without ServerVerify? (y/n)"
        read -r RESPONSE
        if [[ "$RESPONSE" =~ ^[Yy]$ ]]; then
            return 1
        else
            exit 1
        fi
    fi

    # Step 1: Fetch the benchmark run page to get a fresh CSRF token
    echo -e "${YELLOW}Fetching CSRF token...${NC}"
    local PAGE_HTML
    PAGE_HTML=$(curl -s -L -b "$SV_COOKIEJAR" -c "$SV_COOKIEJAR" "https://serververify.com/benchmarks/run" 2>/dev/null)

    if [ -z "$PAGE_HTML" ]; then
        echo -e "${RED}Failed to fetch ServerVerify page${NC}"
        return 1
    fi

    # Verify we're still logged in
    if ! echo "$PAGE_HTML" | grep -q 'action="https://serververify.com/logout"'; then
        echo -e "${RED}Session lost after login — this is unexpected${NC}"
        return 1
    fi

    local CSRF_TOKEN
    CSRF_TOKEN=$(echo "$PAGE_HTML" | grep -oP 'name="csrf-token" content="\K[^"]+')
    if [ -z "$CSRF_TOKEN" ]; then
        CSRF_TOKEN=$(echo "$PAGE_HTML" | grep -oP 'name="_token" value="\K[^"]+' | head -1)
    fi

    if [ -z "$CSRF_TOKEN" ]; then
        echo -e "${RED}Failed to extract CSRF token${NC}"
        return 1
    fi
    echo -e "${GREEN}CSRF token obtained${NC}"

    # Step 2: Get provider ID (PROVIDER_ID is set by search_provider)
    PROVIDER_ID=""
    if [ -n "$SV_PROVIDER" ]; then
        echo -e "${YELLOW}Searching for provider: $SV_PROVIDER${NC}"
        if ! search_provider "$SV_PROVIDER" "$CSRF_TOKEN" "$SV_COOKIEJAR" "interactive"; then
            echo -e "${YELLOW}Provider search failed for '$SV_PROVIDER'${NC}"
        fi
    fi

    # If no provider found/specified, prompt interactively
    if [ -z "$PROVIDER_ID" ]; then
        echo "Enter the provider name to search for:"
        read -r SV_PROVIDER
        if [ -z "$SV_PROVIDER" ]; then
            echo -e "${YELLOW}No provider specified, continuing without ServerVerify${NC}"
            return 1
        fi

        if ! search_provider "$SV_PROVIDER" "$CSRF_TOKEN" "$SV_COOKIEJAR" "interactive"; then
            return 1
        fi
    fi

    # Step 3: POST to create the benchmark
    echo -e "${YELLOW}Creating benchmark on ServerVerify...${NC}"

    local POST_DATA="_token=${CSRF_TOKEN}&provider=${PROVIDER_ID}"
    [ -n "$SV_PRIVATE" ] && POST_DATA="${POST_DATA}&private=${SV_PRIVATE}"
    [ -n "$SV_RECOMMEND" ] && POST_DATA="${POST_DATA}&recommend=${SV_RECOMMEND}"
    [ -n "$SV_COST" ] && POST_DATA="${POST_DATA}&cost=${SV_COST}"
    [ -n "$SV_BILLING" ] && POST_DATA="${POST_DATA}&billing_interval=${SV_BILLING}"

    local RESPONSE_HEADERS="/tmp/sv_response_headers_$$"

    # Don't follow redirects (-L omitted) so we can capture the 302 Location header
    curl -s -D "$RESPONSE_HEADERS" -o /dev/null \
        -b "$SV_COOKIEJAR" -c "$SV_COOKIEJAR" \
        -H "X-CSRF-TOKEN: $CSRF_TOKEN" \
        -X POST "https://serververify.com/benchmarks/run" \
        -d "$POST_DATA" 2>/dev/null

    # The POST returns a 302 redirect to /benchmarks/run/<UUID>
    local REDIRECT_URL
    REDIRECT_URL=$(grep -i '^location:' "$RESPONSE_HEADERS" | tail -1 | tr -d '\r' | awk '{print $2}')

    if [ -z "$REDIRECT_URL" ]; then
        echo -e "${RED}No redirect received from ServerVerify. The form submission may have failed.${NC}"
        echo -e "${YELLOW}Check https://serververify.com/user/benchmarks for your pending benchmarks.${NC}"
        rm -f "$RESPONSE_HEADERS"
        echo "Enter the API URL manually, or press Enter to skip:"
        read -r API_URL
        [ -n "$API_URL" ] && return 0
        return 1
    fi

    echo -e "${GREEN}Benchmark created! Redirect: $REDIRECT_URL${NC}"
    rm -f "$RESPONSE_HEADERS"

    # The benchmark page loads the YABS command dynamically via HTMX from
    # /benchmarks/run/<UUID>/progress — fetch that endpoint for the API URL
    local PROGRESS_URL="${REDIRECT_URL}/progress"
    echo -e "${YELLOW}Fetching progress endpoint for API URL...${NC}"
    local PROGRESS_BODY
    PROGRESS_BODY=$(curl -s -L -b "$SV_COOKIEJAR" -c "$SV_COOKIEJAR" "$PROGRESS_URL" 2>/dev/null)

    # Look for the API URL in the progress response
    API_URL=$(echo "$PROGRESS_BODY" | grep -oP 'https://serververify\.com/api/benchmarks/yabs/[a-f0-9-]+' | head -1)

    if [ -z "$API_URL" ]; then
        API_URL=$(echo "$PROGRESS_BODY" | grep -oP 'serververify\.com/api/benchmarks/yabs/[a-f0-9-]+' | head -1)
        [ -n "$API_URL" ] && API_URL="https://$API_URL"
    fi

    # Fallback: try constructing the URL from the redirect UUID
    if [ -z "$API_URL" ]; then
        local BENCH_UUID
        BENCH_UUID=$(echo "$REDIRECT_URL" | grep -oP '/benchmarks/run/\K[a-f0-9-]+')
        if [ -n "$BENCH_UUID" ]; then
            local CANDIDATE_URL="https://serververify.com/api/benchmarks/yabs/$BENCH_UUID"
            echo -e "${YELLOW}Trying constructed URL: $CANDIDATE_URL${NC}"
            local TEST_RESPONSE
            TEST_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" "$CANDIDATE_URL" 2>/dev/null)
            if [ "$TEST_RESPONSE" != "404" ] && [ "$TEST_RESPONSE" != "000" ]; then
                API_URL="$CANDIDATE_URL"
            fi
        fi
    fi

    if [ -n "$API_URL" ]; then
        echo -e "${GREEN}API URL: $API_URL${NC}"
        return 0
    else
        echo -e "${RED}Failed to extract API URL${NC}"
        echo -e "${YELLOW}Redirect was: $REDIRECT_URL${NC}"
        echo -e "${YELLOW}Progress response:${NC}"
        echo "$PROGRESS_BODY" | head -c 1000
        echo ""
        echo ""
        echo "Enter the API URL manually, or press Enter to skip:"
        read -r API_URL
        [ -n "$API_URL" ] && return 0
        return 1
    fi
}

# Function to run patched yabs (for both IPv4 and IPv6 if Geekbench Pro is available)
run_yabs_patched() {
    local API_ARG="$1"
    local USE_IPV6="$2"  # "true" if IPv6-only system

    if [ "$USE_IPV6" = "true" ]; then
        echo -e "${YELLOW}Downloading and patching YABS for IPv6-only system...${NC}"
    else
        echo -e "${YELLOW}Downloading and patching YABS for Geekbench Pro...${NC}"
    fi

    # Download yabs script
    local YABS_SCRIPT="/tmp/yabs_patched.sh"
    if [ "$USE_IPV6" = "true" ]; then
        if ! curl -6 -sL https://yabs.sh -o "$YABS_SCRIPT" 2>/dev/null; then
            if ! curl -sL https://yabs.sh -o "$YABS_SCRIPT" 2>/dev/null; then
                echo -e "${RED}Failed to download yabs script${NC}"
                return 1
            fi
        fi
    else
        curl -sL https://yabs.sh -o "$YABS_SCRIPT"
    fi

    # Apply patches
    echo -e "${GREEN}Applying patches...${NC}"

    if [ "$USE_IPV6" = "true" ]; then
        # Patch 1: Add IPV4_CHECK_REAL line AFTER the IPV4_CHECK line
        sed -i '/^IPV4_CHECK=/a IPV4_CHECK_REAL="$IPV4_CHECK"' "$YABS_SCRIPT"

        # Patch 2: Now add the fake IPV4_CHECK line AFTER IPV4_CHECK_REAL
        sed -i '/^IPV4_CHECK_REAL=/a IPV4_CHECK="patched"' "$YABS_SCRIPT"

        # Patch 3: Fix display to use IPV4_CHECK_REAL
        sed -i 's|\[\[ -z "\$IPV4_CHECK" \]\] && ONLINE=|[[ -z "$IPV4_CHECK_REAL" ]] \&\& ONLINE=|g' "$YABS_SCRIPT"

        # Patch 4: Fix JSON output to use IPV4_CHECK_REAL
        sed -i 's|IPV4=\$\[ -n "\$IPV4_CHECK" \]|IPV4=$[ -n "$IPV4_CHECK_REAL" ]|g' "$YABS_SCRIPT"

        # Patch 5: Fix iperf to use IPV4_CHECK_REAL (line 930)
        sed -i 's|\[ -n "\$IPV4_CHECK" \] && launch_iperf "IPv4"|[ -n "$IPV4_CHECK_REAL" ] \&\& launch_iperf "IPv4"|g' "$YABS_SCRIPT"
    fi

    # Patch 6: Geekbench URLs (always apply if using Geekbench Pro)
    sed -i 's|https://cdn\.geekbench\.com/Geekbench-[0-9.-]*-Linux\.tar\.gz|https://unreliable.download/Geekbench-6.5.0-Linux.tar.gz|g' "$YABS_SCRIPT"
    sed -i 's|https://cdn\.geekbench\.com/Geekbench-[0-9.-]*-LinuxARMPreview\.tar\.gz|https://unreliable.download/Geekbench-6.5.0-Linux.tar.gz|g' "$YABS_SCRIPT"

    # Patch 7: Unlock (remove quotes)
    sed -i 's|--unlock "\$(cat geekbench.license)"|--unlock $(cat geekbench.license)|g' "$YABS_SCRIPT"

    # Patch 8: Capture full output with --no-upload
    sed -i 's|GEEKBENCH_TEST=\$.*grep "https://browser")|GEEKBENCH_TEST=$("$GEEKBENCH_PATH/$GB_CMD" --no-upload 2>\&1)|g' "$YABS_SCRIPT"

    # Patch 9: URL extraction
    sed -i 's|GEEKBENCH_URL=\$(echo -e "\$GEEKBENCH_TEST".*head -1.*)|GEEKBENCH_URL="Local (--no-upload)"|g' "$YABS_SCRIPT"
    sed -i 's|GEEKBENCH_URL_CLAIM=\$(echo -e "\$GEEKBENCH_TEST".*tail -1.*)|GEEKBENCH_URL_CLAIM=""|g' "$YABS_SCRIPT"

    # Patch 10: GEEKBENCH_SCORES line
    sed -i 's|GEEKBENCH_SCORES=\$(\$DL_CMD "\$GEEKBENCH_URL".*)|GEEKBENCH_SCORES="dummy"|g' "$YABS_SCRIPT"

    # Patch 11: Score parsing (use # as delimiter)
    sed -i 's#GEEKBENCH_SCORES_SINGLE=\$(echo "\$GEEKBENCH_SCORES".*head -n 1)#GEEKBENCH_SCORES_SINGLE=$(echo "$GEEKBENCH_TEST" | grep -oP "Single-Core Score\\s+\\K[0-9]+")#g' "$YABS_SCRIPT"
    sed -i 's#GEEKBENCH_SCORES_MULTI=\$(echo "\$GEEKBENCH_SCORES".*tail -n 1)#GEEKBENCH_SCORES_MULTI=$(echo "$GEEKBENCH_TEST" | grep -oP "Multi-Core Score\\s+\\K[0-9]+")#g' "$YABS_SCRIPT"

    # --- Alpine-specific patches ---
    if is_alpine; then
        # Patch 12 (Alpine): Fix locale detection
        # YABS checks `locale -a | grep ^C$` which fails on Alpine (no locale command).
        # Without LC_ALL=C, fio output parsing breaks and all disk results are zero.
        sed -i 's@if locale -a 2>/dev/null | grep \^C\$ > /dev/null; then@if true; then@' "$YABS_SCRIPT"

        # Patch 13 (Alpine): Run Geekbench inside a Debian Docker container
        # Geekbench is compiled against glibc which is incompatible with Alpine's musl.
        # Instead of fighting symbol mismatches, we run it in a minimal Debian container.
        # Docker shares the host kernel so CPU benchmark results are identical to bare metal.
        if docker info &>/dev/null; then
            echo -e "${YELLOW}Injecting Docker-based Geekbench runner into YABS...${NC}"

            # Create wrapper script that YABS will call instead of the native binary.
            # It receives the same arguments as the real geekbench binary (--unlock, --no-upload, etc.)
            # and runs them inside a Debian container with the Geekbench directory mounted.
            cat > /tmp/gb_docker_wrapper.sh << 'DOCKERWRAPPER'
#!/bin/bash
# Geekbench Docker wrapper — runs the real binary inside Debian container
# Called in place of the geekbench binary by YABS
# GB_DOCKER_PATH = extracted Geekbench directory on the host
# GB_DOCKER_CMD  = original binary name (e.g., "geekbench6")
GB_DIR="$GB_DOCKER_PATH"
GB_BIN="${GB_DOCKER_CMD:-geekbench6}"
if [ -z "$GB_DIR" ]; then
    echo "ERROR: GB_DOCKER_PATH not set" >&2
    exit 1
fi
# Build a tagged image with required runtime libraries on first use.
# debian:bookworm-slim lacks libstdc++ which Geekbench needs.
if ! docker image inspect gb-runner:latest &>/dev/null; then
    echo "Preparing Geekbench Docker environment (one-time)..." >&2
    docker run --name gb-runner-setup debian:bookworm-slim \
        sh -c "apt-get update -qq && apt-get install -y -qq libstdc++6 zlib1g >/dev/null 2>&1"
    docker commit gb-runner-setup gb-runner:latest >/dev/null 2>&1
    docker rm gb-runner-setup >/dev/null 2>&1
fi
# Run geekbench inside Debian container with the host directory mounted
# --pid=host: share host PID namespace so Geekbench sees real CPU topology
docker run --rm \
    --pid=host \
    -v "$GB_DIR":/gb:rw \
    -w /gb \
    gb-runner:latest \
    "/gb/$GB_BIN" "$@"
DOCKERWRAPPER
            chmod +x /tmp/gb_docker_wrapper.sh

            # Replace the geekbench binary invocations in YABS.
            # YABS runs: "$GEEKBENCH_PATH/$GB_CMD" --unlock ... (and later --no-upload)
            # We replace $GB_CMD assignment so it points to our wrapper, and export the path.
            # The GB_CMD variable is set like: GB_CMD="geekbench6"
            # We patch both the unlock and benchmark lines to use docker.

            # After the tarball extraction, replace the geekbench binary with our wrapper
            # and keep the original for the container to use.
            # Save the original GB_CMD (e.g., "geekbench6") so the wrapper knows
            # which binary to exec inside the container, then override GB_CMD.
            sed -i '/tar xz --strip-components=1 -C "\$GEEKBENCH_PATH"/a\
\t\t# Alpine: set up Docker wrapper for Geekbench (musl incompatible with glibc binary)\
\t\texport GB_DOCKER_PATH="$GEEKBENCH_PATH"\
\t\texport GB_DOCKER_CMD="$GB_CMD"\
\t\tcp /tmp/gb_docker_wrapper.sh "$GEEKBENCH_PATH/gb_docker_run.sh"\
\t\tchmod +x "$GEEKBENCH_PATH/gb_docker_run.sh"\
\t\tGB_CMD="gb_docker_run.sh"' "$YABS_SCRIPT"
        else
            echo -e "${RED}Docker not available — Geekbench will likely fail on Alpine${NC}"
        fi
    fi

    chmod +x "$YABS_SCRIPT"

    echo -e "${GREEN}Patches applied successfully. Running YABS...${NC}\n"

    # Build YABS flags
    local YABS_FLAGS=""
    [ "$SKIP_FIO" = true ] && YABS_FLAGS="${YABS_FLAGS} -f"
    [ "$SKIP_IPERF" = true ] && YABS_FLAGS="${YABS_FLAGS} -i"

    # Run yabs
    if [ -n "$API_ARG" ]; then
        bash "$YABS_SCRIPT" -s "$API_ARG" $YABS_FLAGS
    else
        bash "$YABS_SCRIPT" $YABS_FLAGS
    fi

    local EXIT_CODE=$?
    rm -f "$YABS_SCRIPT" /tmp/gb_docker_wrapper.sh
    return $EXIT_CODE
}

# Main script
echo -e "${GREEN}=== YABS Wrapper Script (Login ServerVerify) — Alpine Edition ===${NC}\n"

# Check if running as root
if [ "$EUID" -ne 0 ]; then
    echo -e "${RED}This script requires root privileges for swap management${NC}"
    echo "Please run with sudo or doas"
    exit 1
fi

# Alpine: install dependencies and pull Docker image
if is_alpine; then
    install_alpine_deps
fi

# Check for jq (required for provider search JSON parsing)
if ! command -v jq &>/dev/null; then
    echo -e "${RED}jq is required but not installed.${NC}"
    echo "Install it with: apk add jq"
    exit 1
fi

# Check for IPv6-only
IPV6_ONLY=false
if check_ipv6_only; then
    IPV6_ONLY=true
fi

# Check memory and create swap if needed
if check_memory; then
    if ! create_swap; then
        echo -e "${YELLOW}Failed to create swap, but continuing anyway...${NC}"
    fi
fi

# Get Geekbench Pro license
GB_PRO=false
if get_geekbench_license; then
    GB_PRO=true
fi

# Get ServerVerify API URL
get_serververify_api

# Run YABS
echo -e "\n${GREEN}Starting YABS benchmark...${NC}\n"

# If Geekbench Pro is available, always use patched version
if [ "$GB_PRO" = true ]; then
    echo -e "${YELLOW}Using Geekbench Pro with --no-upload${NC}"
    if [ -n "$API_URL" ]; then
        echo -e "${YELLOW}Running with ServerVerify integration${NC}"
        run_yabs_patched "$API_URL" "$IPV6_ONLY"
    else
        echo -e "${YELLOW}Running without ServerVerify integration${NC}"
        run_yabs_patched "" "$IPV6_ONLY"
    fi
elif [ "$IPV6_ONLY" = true ]; then
    echo -e "${YELLOW}IPv6-only system detected but no Geekbench Pro license${NC}"
    echo -e "${YELLOW}Geekbench will be skipped${NC}"
    EXTRA_FLAGS=""
    [ "$SKIP_FIO" = true ] && EXTRA_FLAGS="${EXTRA_FLAGS} -f"
    [ "$SKIP_IPERF" = true ] && EXTRA_FLAGS="${EXTRA_FLAGS} -i"
    if [ -n "$API_URL" ]; then
        curl -sL https://yabs.sh | bash -s -- -s "$API_URL" $EXTRA_FLAGS
    else
        curl -sL https://yabs.sh | bash -s -- $EXTRA_FLAGS
    fi
else
    # Regular system — still patch for Alpine Docker Geekbench and locale fix
    if is_alpine; then
        echo -e "${YELLOW}Alpine detected — using patched YABS for compatibility${NC}"
        run_yabs_patched "$API_URL" "$IPV6_ONLY"
    elif [ -n "$API_URL" ]; then
        echo -e "${YELLOW}Running with ServerVerify integration${NC}"
        EXTRA_FLAGS=""
        [ "$SKIP_FIO" = true ] && EXTRA_FLAGS="${EXTRA_FLAGS} -f"
        [ "$SKIP_IPERF" = true ] && EXTRA_FLAGS="${EXTRA_FLAGS} -i"
        curl -sL https://yabs.sh | bash -s -- -s "$API_URL" $EXTRA_FLAGS
    else
        echo -e "${YELLOW}Running without ServerVerify integration${NC}"
        EXTRA_FLAGS=""
        [ "$SKIP_FIO" = true ] && EXTRA_FLAGS="${EXTRA_FLAGS} -f"
        [ "$SKIP_IPERF" = true ] && EXTRA_FLAGS="${EXTRA_FLAGS} -i"
        curl -sL https://yabs.sh | bash -s -- $EXTRA_FLAGS
    fi
fi

echo -e "\n${GREEN}=== Benchmark Complete ===${NC}"
