#!/bin/bash

set -e

cd /home/container || {
    echo "ERROR: /home/container does not exist"
    exit 1
}

# Install if needed
if [[ "$BL_INST_FORCE" == "1" ]] || [ ! -f "Blockland.exe" ]; then
    source /usr/local/bin/install-bl
fi

# Required vars
[ -z "$BL_PORT" ] && echo "Missing BL_PORT" && exit 1
[ -z "$BL_GAMEMODE" ] && echo "Missing BL_GAMEMODE" && exit 1

if [[ "$BL_DEDI_LAN" == "1" ]]; then
    dedi="dedicatedLAN"
else
    [ -z "$BL_DTOKEN" ] && echo "Missing BL_DTOKEN" && exit 1
    dedi="dedicated"
fi

# Create wine prefix if missing
if [ ! -d "$HOME/.wine" ]; then
    echo "Creating wine prefix..."
    wineboot -i
    sleep 3
fi

if [ "${BL_UNZIP_ADDONS:-0}" -eq 1 ]; then
    echo "Processing Add-Ons zips..."

    cd /home/container/Add-Ons || exit 1

    for zip in *.zip; do
        [ -f "$zip" ] || continue

        addon_name="${zip%.zip}"

        echo "Extracting $zip..."

        # Extract into a temp directory first
        mkdir -p "__tmp_extract__"
        unzip -o "$zip" -d "__tmp_extract__" >/dev/null

        # Count top-level items in extraction
        item_count=$(find "__tmp_extract__" -mindepth 1 -maxdepth 1 | wc -l)

        if [ "$item_count" -eq 1 ]; then
            first_item=$(find "__tmp_extract__" -mindepth 1 -maxdepth 1)

            if [ -d "$first_item" ]; then
                # Proper folder structure, just move it
                mv "$first_item" .
            else
                # Single loose file — fix structure
                mkdir -p "$addon_name"
                mv "$first_item" "$addon_name"/
            fi
        else
            # Multiple loose files — put them in folder
            mkdir -p "$addon_name"
            mv "__tmp_extract__"/* "$addon_name"/
        fi

        rm -rf "__tmp_extract__"
        rm -f "$zip"
    done
fi

# Sync Add-On from git repository if BL_ADDON_REPO is set (only on reboot; only pulls when remote has updates)
if [ -n "$BL_ADDON_REPO" ]; then
    # Log HTTPS userinfo redacted (password/token); SSH URLs shown as-is
    bl_redact_git_remote_url() {
        case "$1" in
            http://*|https://*)
                echo "$1" | sed -E 's#(https?://)[^/@]+@#\1***@#'
                ;;
            *)
                echo "$1"
                ;;
        esac
    }

    # Pelican/Wings often use a pipe for the console: stdout is block-buffered, so plain echo can
    # appear "stuck" while git writes to stderr. Use stderr for all addon diagnostics.
    bl_addon_log() {
        printf '%s\n' "$*" >&2
    }

    # Periodic lines while git runs (clone/fetch can look frozen in the panel otherwise)
    bl_git_with_heartbeat() {
        local label="$1"
        shift
        (
            while sleep 15; do
                printf '[BL_ADDON_REPO] %s — still running (%s). Slow network, huge repo, or waiting on auth/firewall.\n' \
                    "$label" "$(date -u +'%Y-%m-%d %H:%M:%S UTC')" >&2
            done
        ) &
        local _hb=$!
        if command -v stdbuf >/dev/null 2>&1; then
            stdbuf -oL -eL "$@"
        else
            "$@"
        fi
        local _rc=$?
        kill "$_hb" 2>/dev/null
        wait "$_hb" 2>/dev/null
        return "$_rc"
    }

    _repo_safe=$(bl_redact_git_remote_url "$BL_ADDON_REPO")
    bl_addon_log "Syncing Add-On from git repository..."
    bl_addon_log "[BL_ADDON_REPO] Remote (credentials redacted): ${_repo_safe}"
    if [ -n "$BL_ADDON_REPO_BRANCH" ]; then
        bl_addon_log "[BL_ADDON_REPO] Branch: ${BL_ADDON_REPO_BRANCH}"
    else
        bl_addon_log "[BL_ADDON_REPO] Branch: (repository default — not set)"
    fi
    bl_addon_log "[BL_ADDON_REPO] Target folder under Add-Ons: $(basename "$BL_ADDON_REPO" .git)"
    bl_addon_log "[BL_ADDON_REPO] If clone/fetch hangs or fails in the panel:"
    bl_addon_log "  • No interactive login in Docker — private HTTPS repos usually need user + token IN the URL, e.g."
    bl_addon_log "      https://YOUR_USER:YOUR_TOKEN@github.com/org/repo.git"
    bl_addon_log "    (GitHub/GitLab: use a personal access token or deploy token, not your web password.)"
    bl_addon_log "  • Or use SSH (git@host:org/repo.git) with a deploy key available inside the container."
    # Avoid indefinite hang waiting for a TTY password prompt (headless)
    export GIT_TERMINAL_PROMPT=0
    # Do not invoke a credential helper that might block without a TTY
    export GIT_ASKPASS=/bin/false

    # Abort if transfer stalls (bytes/sec below limit for lowSpeedTime seconds)
    _git_slow=( -c "http.lowSpeedLimit=500" -c "http.lowSpeedTime=120" )

    mkdir -p /home/container/Add-Ons
    cd /home/container/Add-Ons

    repo_name=$(basename "$BL_ADDON_REPO" .git)

    if [ -d "$repo_name/.git" ]; then
        bl_addon_log "[BL_ADDON_REPO] Existing clone at ${repo_name}/ — fetching..."
        cd "$repo_name"
        if ! bl_git_with_heartbeat "git fetch" git "${_git_slow[@]}" fetch --progress origin; then
            bl_addon_log "[BL_ADDON_REPO] ERROR: git fetch failed (auth, network, or stall). Remote (redacted): ${_repo_safe}"
            exit 1
        fi
        upstream=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null)
        behind=$(git rev-list HEAD.."${upstream:-origin/HEAD}" --count 2>/dev/null || echo 0)
        if [ "${behind:-0}" -gt 0 ]; then
            bl_addon_log "[BL_ADDON_REPO] Remote is ahead — pulling (--ff-only)..."
            if ! bl_git_with_heartbeat "git pull" git "${_git_slow[@]}" pull --ff-only --progress; then
                bl_addon_log "[BL_ADDON_REPO] ERROR: git pull failed. Remote (redacted): ${_repo_safe}"
                exit 1
            fi
        else
            bl_addon_log "[BL_ADDON_REPO] Add-On is up to date (no new commits on tracked branch)."
        fi
        cd /home/container/Add-Ons
    else
        bl_addon_log "[BL_ADDON_REPO] No existing clone — starting git clone (this may take a while)..."
        clone_opts=(--progress --verbose)
        [ -n "$BL_ADDON_REPO_BRANCH" ] && clone_opts+=(-b "$BL_ADDON_REPO_BRANCH")
        if ! bl_git_with_heartbeat "git clone" git "${_git_slow[@]}" clone "${clone_opts[@]}" "$BL_ADDON_REPO"; then
            bl_addon_log "[BL_ADDON_REPO] ERROR: git clone failed. Check URL, auth, branch name, and network."
            bl_addon_log "[BL_ADDON_REPO] Remote used (redacted): ${_repo_safe}"
            exit 1
        fi
        bl_addon_log "[BL_ADDON_REPO] Clone finished successfully."
    fi

    cd /home/container || exit 1
fi

# Ensure we're in the correct directory (server root where Blockland.exe lives)
cd /home/container || exit 1

if [ ! -f "Blockland.exe" ]; then
    echo "Blockland.exe not found!"
    exit 1
fi

echo "Launching Blockland..."

server_name_args=()
[ -n "$BL_SERVER_NAME" ] && server_name_args=(-serverName "$BL_SERVER_NAME")

max_players_args=()
[ -n "$BL_MAX_PLAYERS" ] && max_players_args=(-maxPlayers "$BL_MAX_PLAYERS")

exec xvfb-run -a wine "Blockland.exe" \
    ptlaaxobimwroe \
    -${dedi} \
    -port "$BL_PORT" \
    -dtoken "$BL_DTOKEN" \
    -gamemode "$BL_GAMEMODE" \
    "${server_name_args[@]}" \
    "${max_players_args[@]}" \
    $BL_EXTRA_ARGS